I wrote a demo below for the test React controlled component input feature. But It seems there is a bug.
class TestComponent extends React.Component{
constructor() {
super();
this.state = {value: 'beef'};
this.handleValueChange = this.handleValueChange.bind(this);
}
handleValueChange(e) {
this.setState({value: e.target.value});
}
render() {
return <div>
<div><input type='text' value={'hello world'} onChange={this.handleValueChange}/></div>
<div><input type='text' value={''} onChange={this.handleValueChange}/></div>
<div><input type='text' value={this.state.value} onChange={this.handleValueChange}/></div>
<div><input type='text' value={null} onChange={this.handleValueChange}/></div>
<div><input type='text' value={undefined} onChange={this.handleValueChange}/></div>
<hr/>
<div><input type='text' defaultValue={this.state.value} onChange={this.handleValueChange}/></div>
<p>{this.state.value}</p>
</div>
}
}
ReactDOM.render(
<TestComponent />,
document.body
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
The first one input with specifying string value property. when I type something, call handleValueChange function, and the result is hello world + your type thing's first character.
The second one input with empty string value property. when I type something, it calls handleValueChange function, but finally, it always gives me one character.
It's weird.
updated!
I add a input with defaultValue, compare with value={this.state.value}, my head is mess up..
As mentioned in a comment below your question: remove value={''} since this will empty the input everytime it's rendered.
From the react docs, the correct way to do it is
return <div>
<input type='text' value={this.state.value} onChange={this.handleValueChange}/>
<p>{this.state.value}</p>
</div>
This way whenever you type something in the input-area, you'll update the value set in state.
If you want to render the component with a value set in state, you could use:
getInitialState() {
return { value: 'Your default value'}
}
Or, as already suggested, use defaultValue.
Read more here: https://facebook.github.io/react/docs/forms.html
Update:
According to your updated question, I think you'll have to understand what setting a value during render function actually does. Whenever you set a value during render function, you'll "lock" the input field to be that specific value. Meaning the user input will have no effect on the rendered element. From the docs: "User input will have no effect on the rendered element because React has declared the value".
To solve this problem, you'll have to set the value to be something you can change dynamically, in your case that will be value or this.state.value. Like you've done in your third example:
<input type='text' value={this.state.value} onChange={this.handleValueChange}/>
This way React accept the value provided by the user input and will then update the value of the component thereafter.
I still think the docs specifies this pretty clearly, and I think you should read the provided documentation in my original answer.
Update 2
To clearify the part with controlled and uncontrolled components little bit:
A controlled component is a component that has a value property assigned, and will reflect the value from the user input (the value prop).
While an uncontrolled component does not have any value property assigned, and will NOT reflect the value from the user input (since it does not provide any value prop). But if you want to instantiate an uncontrolled component with a value, you should use defaultValue.
In your case (since you try to use a CONTROLLED component) this means that you should NOT use defaultValue, and stick with a correct implementation of a controlled component. That is an implementation using value={this.state.value}.
Again I recommend reading the docs provided. It's actually not that difficult if you manage to understand the docs.
Hope this clearifies some of you problems! :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With