【问题标题】:Why can't I change my input value in React even with the onChange listener为什么即使使用 onChange 监听器我也不能在 React 中更改我的输入值
【发布时间】:2017-06-03 19:44:54
【问题描述】:

我对 React 很陌生,在学习了一些教程之后,我尝试了下面的代码。

我制作了一个组件,在 componentWillMount 上将道具从商店传递给它,我为组件创建了一个新状态。渲染到现在都很好。

接下来,我将state 绑定到输入框的值,并且我还有onChange 侦听器。不过,我无法更改我在该字段中的值。

由于我来自 Angular 背景,我假设将输入值绑定到如下状态将自动更新 state 对象中的属性 name。我错了吗?

componentWillMount(){
    this.setState({
        updatable : false,
        name : this.props.name,
        status : this.props.status
    });
}

//relevant DOM from component's render function
<input className="form-control" type="text" value={this.state.name} id={'todoName' + this.props.id} onChange={this.onTodoChange.bind(this)}/>

onTodoChange(){
    console.log(this);
    //consoling 'this' here, shows old values only.
    //not sure how and even if I need to update state here.
    // Do I need to pass new state to this function from DOM
    //TODO: send new data to store
}

我的onTodoChange 函数控制台this 的值与初始化时的状态值相同。如何通过在输入框中输入来更改状态,以便将它们发送到商店?

【问题讨论】:

    标签: javascript reactjs state onchange


    【解决方案1】:

    与 Angular 不同,在 React.js 中,您需要手动更新状态。你可以这样做:

    <input
        id={'todoName' + this.props.id}
        className="form-control"
        type="text"
        value={this.state.name}
        onChange={e => this.onTodoChange(e.target.value)}
    />
    

    然后在函数中:

    onTodoChange(value){
            this.setState({
                 name: value
            });
        }
    

    另外,你可以在组件的构造函数中设置初始状态:

      constructor (props) {
        super(props);
        this.state = {
            updatable: false,
            name: props.name,
            status: props.status
        };
      }
    

    【讨论】:

    • 谢谢...我假设构造函数默认接收props。对吗??
    • 正确。记得调用 super(props);
    • 为什么会这样?这种行为是否有根源及其原因?
    【解决方案2】:

    如果你想简单地改变状态变量而不在顶部声明一个新函数,你可以通过内联函数做快捷方式:

    <input type="text" onChange={e => this.setState({ text: e.target.value })}/>
    

    【讨论】:

      【解决方案3】:

      我认为这是最适合你的方式。

      你应该添加这个:this.onTodoChange = this.onTodoChange.bind(this)

      而你的函数有事件param(e),并获取值:

      componentWillMount(){
              this.setState({
                  updatable : false,
                  name : this.props.name,
                  status : this.props.status
              });
          this.onTodoChange = this.onTodoChange.bind(this)
          }
          
          
      <input className="form-control" type="text" value={this.state.name} id={'todoName' + this.props.id} onChange={this.onTodoChange}/>
      
      onTodoChange(e){
               const {name, value} = e.target;
              this.setState({[name]: value});
         
      }
      

      【讨论】:

        【解决方案4】:

        在 React 中,只有当状态或道具发生变化时,组件才会重新渲染(或更新)。

        在您的情况下,您必须在更改后立即更新状态,以便组件使用更新状态值重新渲染。

        onTodoChange(event) {
                // update the state
            this.setState({name: event.target.value});
        }
        

        【讨论】:

          【解决方案5】:

          在反应中,状态不会改变,直到你使用this.setState({});。 这就是您的控制台消息显示旧值的原因。

          【讨论】:

            【解决方案6】:

            如果您想使用一个处理程序处理多个输入,请查看我使用computed property 根据名称获取输入值的方法。

            import React, { useState } from "react";
            import "./style.css";
            
            export default function App() {
              const [state, setState] = useState({
                name: "John Doe",
                email: "john.doe@test.com"
              });
            
              // We need to spread the previous state and change the one we're targeting, so other data cannot be lost.
              const handleChange = e => {
                setState(prevState => {
                  ...prevState,
                  [e.target.name]: e.target.value,
                });
              };
            
              return (
                <div>
                  <input
                    type="text"
                    className="name"
                    name="name"
                    value={state.name}
                    onChange={handleChange}
                  />
            
                  <input
                    type="text"
                    className="email"
                    name="email"
                    value={state.email}
                    onChange={handleChange}
                  />
                </div>
              );
            }
            

            【讨论】:

            • 此方法将删除除刚刚修改的属性之外的所有属性,请参见此处:codesandbox.io/s/zen-sammet-jyp6r 可以使用setState(state =&gt; ({...state, [e.target.name]: e.target.value}))
            • 马克西米利安彼得斯是对的。只是 React React's event pooling 而失败。 namevalue 应该分配给 setState 更新函数之外的局部变量。
            猜你喜欢
            • 2023-03-20
            • 2021-10-14
            • 2020-09-02
            • 2021-03-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-07-07
            相关资源
            最近更新 更多