Mabeh Al-Zuq Yadeek Mabeh Al-Zuq Yadeek - 7 days ago 6
React JSX Question

Change input field when state changes after user input

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?

Answer

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