为什么即使使用 onChange 侦听器我也不能在 React 中更改我的输入值

Why can't I change my input value in React even with the onChange listener

我是 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 的值与初始化时具有相同的状态值。如何通过在输入框中输入来更改状态,以便我可以将它们发送到商店?

在 React 中,组件将 re-render(或更新)仅当状态或 prop 发生变化时。

在您的情况下,您必须在更改后立即更新状态,以便组件 re-render 具有更新的状态值。

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

在 React 中,只有使用 this.setState({}); 才能更改状态。 这就是为什么您的控制台消息显示旧值的原因。

与 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
    };
  }

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

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

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

您应该添加: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});
   
}

如果您想使用一个处理程序处理多个输入,请查看我使用 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>
  );
}