如何使用ReactJS获取输入字段的值?

2020/10/18 06:01 · javascript ·  · 0评论

我有以下React组件:

export default class MyComponent extends React.Component {

    onSubmit(e) {
        e.preventDefault();
        var title = this.title;
        console.log(title);
    }

    render(){
        return (
            ...
            <form className="form-horizontal">
                ...
                <input type="text" className="form-control" ref={(c) => this.title = c} name="title" />
                ...
            </form>
            ...
            <button type="button" onClick={this.onSubmit} className="btn">Save</button>
            ...
        );
    }

};

控制台给了我undefined-任何想法这段代码有什么问题吗?

您应该在类MyComponent下使用构造函数扩展React.Component

constructor(props){
    super(props);
    this.onSubmit = this.onSubmit.bind(this);
  }

然后您将获得标题的结果

这里有三个答案,这取决于您(被迫使用)React的版本以及是否要使用挂钩。

第一件事:

理解React的工作原理很重要,这样您就可以正确地做事(提示:在React网站上运行React教程练习非常值得的。它写得很好,并涵盖了所有基本知识,实际上是在解释如何做。东西)。这里的“正确”表示您正在编写一个恰好在浏览器中呈现的应用程序接口;所有界面工作都在React中进行,而不是在“编写网页时的习惯”中进行(这就是为什么React应用是“应用”而不是“网页”的原因)。

React应用程序基于以下两个方面进行呈现:

  1. 由任何父级创建的组件实例的实例声明的组件属性,父级可以在其整个生命周期中对其进行修改,并且
  2. 组件自身的内部状态,可以在其整个生命周期中对其进行修改。

当您使用React时,您显然没有做的事情是生成HTML元素,然后使用它们:<input>例如,当您告诉React使用一个时,您不是在创建HTML输入元素,而是在告诉React创建一个React输入对象恰好呈现为HTML输入元素,并且其事件处理着眼于但不受HTML元素的输入事件控制。

使用React时,您正在做的是生成应用程序UI元素,这些元素向用户呈现(通常是可操作的)数据,并且用户交互会更改Component的状态,这可能导致应用程序界面的一部分重新呈现以反映新状态。在此模型中,状态始终是最终的权限,而不是“使用任何UI库呈现状态”,而状态权在网络上是浏览器的DOM。在这个编程模型中,DOM几乎是事后才想到的:它只是React恰好使用的特定UI框架。

因此,对于输入元素,逻辑为:

  1. 您输入输入元素,
  2. 您的输入元素没有任何反应,该事件被React拦截并立即终止
  3. React将事件转发到您为事件处理设置的功能,
  4. 该功能可以安排状态更新,
  5. 如果是这样,React将运行状态更新(异步!),并render在更新后触发调用,但前提是状态更新更改了状态。
  6. 只有在进行此渲染之后,UI才会显示您“键入了字母”。

所有这些操作大约需要几毫秒,甚至更短的时间,因此,看起来就像您从“仅在页面上使用输入元素”一样,以相同的方式键入input元素,但这绝对不是发生了

因此,说到如何从React中的元素获取值:

使用ES5的React 15及以下版本

为了正确执行操作,您的组件具有一个状态值,该状态值通过输入字段显示,我们可以通过使UI元素将更改事件发送回该组件来对其进行更新:

var Component = React.createClass({
  getInitialState: function() {
    return {
      inputValue: ''
    };
  },

  render: function() {
    return (
      //...
      <input value={this.state.inputValue} onChange={this.updateInputValue}/>
      //...
    );
  },

  updateInputValue: function(evt) {
    this.setState({
      inputValue: evt.target.value
    });
  }
});

所以我们告诉反应使用updateInputValue函数来处理用户交互,使用setState调度状态更新,而事实上,render接进this.state.inputValue的手段,当它更新状态后重新渲染,用户将看到基于他们键入的内容更新文本。

基于评论的附录

假设UI输入代表状态值(请考虑如果用户在中途关闭其选项卡并还原了该标签会发生什么。是否应该还原他们填写的所有这些值?如果是,那就是状态)。这可能会让您觉得大型表单需要数十个甚至一百个输入表单,但是React是关于以一种可维护的方式对UI建模:您没有100个独立的输入字段,有相关的输入组,因此您捕获了每个输入组合成一个组件,然后将“主”表单构建为一组组合。

MyForm:
  render:
    <PersonalData/>
    <AppPreferences/>
    <ThirdParty/>
     ...

这也比巨型单一表单组件容易维护。通过状态维护将组划分为组件,其中每个组件仅负责一次跟踪几个输入字段。

您可能还觉得写出所有这些代码是“麻烦”,但这是不正确的节省:那些不是您(包括未来的您)的开发人员实际上会从看到所有这些明确输入中受益匪浅,因为它使代码路径更容易跟踪。但是,您始终可以进行优化。例如,您可以编写状态链接器

MyComponent = React.createClass({
  getInitialState() {
    return {
      firstName: this.props.firstName || "",
      lastName: this.props.lastName || "" 
      ...: ...
      ...
    }
  },
  componentWillMount() {
    Object.keys(this.state).forEach(n => {
      let fn = n + 'Changed';
      this[fn] = evt => {
        let update = {};
        update[n] = evt.target.value;
        this.setState(update);
      });
    });
  },
  render: function() {
    return Object.keys(this.state).map(n => {
      <input
        key={n} 
        type="text"
        value={this.state[n]}
        onChange={this[n + 'Changed']}/>
    });
  }
});

当然,对此有改进的版本,因此请访问https://npmjs.com并搜索您最喜欢的React状态链接解决方案。开源主要是寻找他人已经完成的工作,而不是从头开始编写所有内容。

React 16(和15.5过渡版)和``现代''JS

从React 16开始(以及从15.5开始软启动),createClass不再支持调用,并且需要使用类语法。这会改变两件事:明显的类语法,this以及createClass可以“免费”执行上下文绑定,因此要确保一切仍然正常,请确保使用“胖箭头”符号thisonWhatever处理程序中保留上下文的匿名函数,例如在onChange这里的代码中,我们使用:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: ''
    };
  }

  render() {
    return (
      //...
      <input value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)}/>
      //...
    );
  },

  updateInputValue(evt) {
    this.setState({
      inputValue: evt.target.value
    });
  }
});

您可能还已经看到人们bind在其构造函数中使用其所有事件处理功能,如下所示:

constructor(props) {
  super(props);
  this.handler = this.handler.bind(this);
  ...
}

render() {
  return (
    ...
    <element onclick={this.handler}/>
    ...
  );
}

不要那样做

几乎在您每次使用时bind,都会出现谚语“您做错了”。您的类已经定义了对象原型,因此已经定义了实例上下文。不要放在首位bind使用普通事件转发而不是在构造函数中复制所有函数调用,因为这种复制会增加您的错误面,并且使跟踪错误变得更加困难,因为问题可能出在构造函数中而不是代码所在位置。以及给您(拥有或选择)与之共事的其他人增加维护负担。

是的,我知道react docs说很好。不是,不要这样做。

使用带钩子的功能组件进行React 16.8

从React 16.8开始,函数组件(即从字面上仅以某些props参数作为参数的函数就可以使用,就好像它是组件类的实例,而无需编写类)也可以通过使用hooks来获得状态

如果您不需要完整的类代码,并且只需一个实例函数,那么现在可以使用该useState钩子为自己获取一个状态变量及其更新功能,该变量的工作原理与上述示例大致相同,不同之处在于:该setState函数调用:

import { useState } from 'react';

function myFunctionalComponentFunction() {
  const [input, setInput] = useState(''); // '' is the initial state value
  return (
    <div>
    <label>Please specify:</label>
    <input value={input} onInput={e => setInput(e.target.value)}/>
    </div>
  );
}

以前,类和功能组件之间的非正式区别是“功能组件没有状态”,因此我们再也无法躲藏起来:功能组件和类组件之间的差异可以很好地分布在几页上编写的反应文档(没有捷径说明可以方便地为您造成误解!),您应该阅读该文档,以便您知道自己在做什么,从而可以知道自己是否选择了最佳的(无论对您而言意味着什么)编程方案摆脱您遇到的问题。

通过执行以下操作来设法获取输入字段的值:

import React, { Component } from 'react';

class App extends Component {

constructor(props){
super(props);

this.state = {
  username : ''
}

this.updateInput = this.updateInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}


updateInput(event){
this.setState({username : event.target.value})
}


handleSubmit(){
console.log('Your input value is: ' + this.state.username)
//Send state to the server code
}



render(){
return (
    <div>
    <input type="text" onChange={this.updateInput}></input>
    <input type="submit" onClick={this.handleSubmit} ></input>
    </div>
  );
}
} 

//output
//Your input value is: x

在反应16中,我使用

<Input id="number" 
       type="time" 
       onChange={(evt) => { console.log(evt.target.value); }} />

通过将“ this”绑定到函数updateInputValue(evt),我成功地做到了

this.updateInputValue = this.updateInputValue.bind(this);

但是,输入值= {this.state.inputValue} ...并不是一个好主意。

这是babel ES6的完整代码:

class InputField extends React.Component{


  constructor(props){
   super(props);
   //this.state={inputfield: "no value"};   
   this.handleClick = this.handleClick.bind(this);
   this.updateInputValue = this.updateInputValue.bind(this);
  }

  handleClick(){
   console.log("trying to add picture url");
   console.log("value of input field : "+this.state.inputfield);

  }

  updateInputValue(evt){
    //console.log("input field updated with "+evt.target.value);
    this.state={inputfield: evt.target.value};   

  }

  render(){
    var r; 
    r=<div><input type="text" id="addpixinputfield" 
            onChange={this.updateInputValue} />
      <input type="button" value="add" id="addpix" onClick={this.handleClick}/>
      </div>;    
    return r;
   }
}

您的错误是因为您使用了类,并且在使用类时,我们需要使用This绑定函数才能正常工作。无论如何,有很多教程为什么我们应该在JavaScript中执行“ this”和“ this”是什么。

如果您更正提交按钮,则应该可以:

<button type="button" onClick={this.onSubmit.bind(this)} className="btn">Save</button>

并且如果您想在控制台中显示该输入的值,则应该使用var title = this.title.value;。

给出<input>一个唯一的ID

<input id='title' ...>

然后使用标准的Web API在DOM中引用它

const title = document.getElementById('title').value

无需每次按键都不断更新React状态。只需在需要时获取值即可。

// On the state
constructor() {
  this.state = {
   email: ''
 }
}

// Input view ( always check if property is available in state {this.state.email ? this.state.email : ''}

<Input 
  value={this.state.email ? this.state.email : ''} 
  onChange={event => this.setState({ email: event.target.value)}
  type="text" 
  name="emailAddress" 
  placeholder="johdoe@somewhere.com" />

您无需添加“ onChange”功能就可以获取输入值。

只需在输入元素中添加一个'ref attr:

然后在需要时使用this.refs获取输入值。

将您的引用更改为:ref='title'并删除name='title'
然后删除
var title = this.title并写入:

console.log(this.refs.title.value)

您还应该添加.bind(this)this.onSubmit

(在我的情况下,它的工作原理非常相似,但是代替了onClickonSubmit={...},它以(<form onSubmit={...} ></form>)形式出现

如果使用类组件,则只需3个步骤-首先,您需要声明输入字段的状态,例如this.state = {name:''}其次,在下面的示例中,您需要编写一个用于设置状态更改时的状态的函数,即setName(),最后必须编写输入jsx,例如 <输入值= {this.name} onChange = {this.setName} />

import React, { Component } from 'react'

export class InputComponents extends Component {
    constructor(props) {
        super(props)

        this.state = {
             name:'',
             agree:false
        }
        this.setName = this.setName.bind(this);
        this.setAgree=this.setAgree.bind(this);
    }

    setName(e){
        e.preventDefault();
        console.log(e.target.value);
        this.setState({
            name:e.target.value
        })
    }
    setAgree(){
        this.setState({
            agree: !this.state.agree
        }, function (){
            console.log(this.state.agree);
        })
    }
    render() {
        return (
            <div>
                <input type="checkbox" checked={this.state.agree} onChange={this.setAgree}></input>
                < input value={this.state.name} onChange = {this.setName}/>
            </div>
        )
    }
}

export default InputComponents
export default class MyComponent extends React.Component {

onSubmit(e) {
    e.preventDefault();
    var title = this.title.value; //added .value
    console.log(title);
}

render(){
    return (
        ...
        <form className="form-horizontal">
            ...
            <input type="text" className="form-control" ref={input => this.title = input} name="title" />
            ...
        </form>
        ...
        <button type="button" onClick={this.onSubmit} className="btn">Save</button>
        ...
    );
}

};

使用不受控制的字段:

export default class MyComponent extends React.Component {

    onSubmit(e) {
        e.preventDefault();
        console.log(e.target.neededField.value);
    }

    render(){
        return (
            ...
            <form onSubmit={this.onSubmit} className="form-horizontal">
                ...
                <input type="text" name="neededField" className="form-control" ref={(c) => this.title = c} name="title" />
                ...
            </form>
            ...
            <button type="button" className="btn">Save</button>
            ...
        );
    }

};

最简单的方法是使用箭头功能

您的带有箭头功能的代码

export default class MyComponent extends React.Component {

onSubmit = (e) => {
    e.preventDefault();
    var title = this.title;
    console.log(title);
}

render(){
    return (
        ...
        <form className="form-horizontal">
            ...
            <input type="text" className="form-control" ref={(c) => this.title = c} name="title" />
            ...
        </form>
        ...
        <button type="button" onClick={this.onSubmit} className="btn">Save</button>
        ...
    );
}

};

本文地址:http://javascript.askforanswer.com/ruheshiyongreactjshuoqushuruziduandezhi.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!