关于 React JS 中的引用/我可以使用引用来设置组件的状态吗?

Regarding refs in react JS / Can I use a ref to set component's state?

在下面的代码中,我无法使用 this.setState({name: this.nameRef.current.value})。有人可以告诉为什么会这样吗?一旦我在 ref 的当前值中有了一些东西,为什么我不能用它来更新组件的当前状态?另外,这是错误的做法吗?不过不行也没关系

class App extends React.Component {
  constructor(){
    console.log('constructor');
    super();
    this.state = {name : '', password: ''}
    this.nameRef = React.createRef()
    this.pwdRef = React.createRef()
  }

  handleLogin = (val) =>{
      val.preventDefault();
      this.setState({name: this.nameRef.current.value}) //Not working
      alert("Welcome"+this.nameRef.current.value);
      console.log(this.state.name); //Outputs empty string
  }
    render(){
      return(
        <React.Fragment>
          <form>
            <div className={"form-group"}>
              <label>Username: </label>
              <input style={{width: '60%', display: 'inline'}} name="name" type="text" className={"form-control"} placeholder="Enter name" ref={this.nameRef}/>
            </div>
            <div className={"form-group"}>
              <label>Password: </label>
              <input style={{width: '60%', display: 'inline'}} type="text" name="pass" className={"form-control"} placeholder="Enter password" ref={this.pwdRef}/>
            </div>
            <button type="submit" className={"btn btn-primary"} onClick={this.handleLogin}> Login </button>
          </form>
        </React.Fragment>
        )
    }
}

export default App;

提前致谢!

不是最佳做法。在你的输入中添加一个 onChange 道具,例如:

onChangeName = e => this.setState({ name: e.target.value });

...

<input ...other things... onChange={this.onChangeName} value={this.state.name} />

这样,每当用户键入输入时,都会自动更新状态。 Refs 应该谨慎使用,因为 React 通常有更好的方法来完成大多数事情。

在回答您的问题之前,您应该做的是将每个输入的值跟踪到相应的状态变量。您可以使用 onChange 侦听器执行此操作(您通过 event.target.value)

获取值

但是,要解决这个问题,您要问的是是否可以使用 refs 从组件中获取值并使用它。你可以,而且你应该看到这个值,我认为它正在发生的是输入没有更新 'value'(当你用 onChange 和 value={this.state.variableName} 控制它时你会更新) .在实现 onChange 和东西后尝试使用 ref 记录输入值,看看它是否改变

嗯,我不知道为什么当我点击提交时我不能设置状态但是 onChange() 解决了我的问题。这很好用:

class App extends React.Component {
  constructor(){
    console.log('constructor');
    super();
    this.state={name: '',password: ''}
    this.nameRef = React.createRef()
    this.pwdRef = React.createRef()
  }

  setStat1 = () =>{
    this.setState({name: this.nameRef.current.value})
  }

  setStat2 = () =>{
    this.setState({password: this.pwdRef.current.value})
  }

  handleLogin = (val) =>{
    console.log(this.state.name+" : "+this.state.password)
      val.preventDefault();
      alert("Welcome"+this.nameRef.current.value);
  }
    render(){
      return(
        <React.Fragment>
          <form>
            <div className={"form-group"}>
              <label>Username: </label>
              <input style={{width: '60%', display: 'inline'}} name="name" type="text" className={"form-control"} onChange={this.setStat1} placeholder="Enter name" ref={this.nameRef}/>
            </div>
            <div className={"form-group"}>
              <label>Password: </label>
              <input style={{width: '60%', display: 'inline'}} type="text" name="pass" className={"form-control"} placeholder="Enter password" onChange={this.setStat2} ref={this.pwdRef}/>
            </div>
            <button type="submit" className={"btn btn-primary"} onClick={this.handleLogin}> Login </button>
          </form>
        </React.Fragment>
        )
    }
}