0

I'm trying to find a more React-type way of changing the input field when the state changes after a user input. This is my current setup, but I'm looking for a way to do this without signaling to the DOM in the componentWillReceiveProps method:

export default class Example extends React.Component {

constructor(props){
  super(props);
  this.state = {title: props.arr.question};
};

componentWillReceiveProps(nextProps){
  if(nextProps.arr.question !== this.state.title){
    let id = "question" + this.props.arr.key;
    document.getElementById(id).value = nextProps.arr.question;
    this.setState({title: nextProps.arr.question});
  }
}
  render(){

  return(<div>
<input type="text" id={"question" + this.props.arr.key} defaultValue={this.state.title} placeholder="Enter your title."/>
          </div>
        )
  }
}

What I assumed was that when the state changes, I will see the input change as well. In fact, that happens for any element except input fields, for some reason. So the only think that I found works is referencing the DOM in the componentWillReceiveProps method and change it like that.

Is there a better way to do this that I'm unaware of?

1 Answer 1

1

You can create a controlled component by setting the value in your input directly with the value within your state. Check out my answer here, the application is similar.

So in your code be amended to:

export default class Example extends React.Component {

constructor(props){
  super(props);
  this.state = {title: props.arr.question};
  this.handleTitleChange = this.handleTitleChange.bind(this); 
  // ^--necessary to be able to call setState
};

handleTitleChange(e){
  this.setState({title: event.target.value});
  // this updates the state as the user types into the input
  // which also causes a re-render of this component
  // with the newly update state
}
render(){

  return(
     <div>
      <input type="text" 
        id={"question" + this.props.arr.key}
        defaultValue={this.state.title} 
        placeholder="Enter your title."
        onChange={this.handleTitleChange}  // to handle the change

        value={this.state.title}/>  // here is where you set 
                                    // the value to current state
     </div>
  )
}
Sign up to request clarification or add additional context in comments.

3 Comments

So basically create a separate component just for the input?
No, you don't have to. I've added the amendments you could make to your code to get this working.
Only difference is that in my input for this particular question, I'm not directly entering the title in this specific input, but another one. But your solution worked. All I had to do was remove the defaultValue props, add an onChange prop and let the onChange handle the title change by setting the state, instead of calling DOM directly via vanilla JS.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.