Search code examples
reactjsrefreact-ref

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


In the code below I'm unable to use this.setState({name: this.nameRef.current.value}). Can someone please tell why is this happening? Once I've something in ref's current value, why can't I use it to update the component's current state? Also, Is it a wrong practise? However it doesn't matter If it doesn't work.

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;

Thanks in advance!


Solution

  • Well, I don't know why can't I set the state when I click Submit but onChange() solved my issue. This works just fine :

    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>
            )
        }
    }