Reputation: 828
I have a child component that receives props from a parent. In the child component it renders a couple radio buttons like this:
<div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={this._handleInputChange}
value="1"
checked={this.props.value === "1"}
/>
True
</label>
</div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={this._handleInputChange}
value="0"
checked={this.props.value === "0"}
/>
False
</label>
</div>
</div>
handleInputChange just calls a parent method like so:
_handleInputChange(e) {
this.props.handleChange(e);
}
that will set the state of the parent component to the value selected in the radio buttons (i.e. "1" or "0"). The issue im having is that the checked conditionals return the correct props, but they function strangely. It almost seems like when the radio input receives a new prop value, it doesn't re render with checked
. When the component first renders, the props.value is an empty string. When a user selects a radio button it changes the state of the parent component with _handleInputChange
and then sends that value back down for the conditionals.
Upvotes: 4
Views: 23870
Reputation: 1080
You must use state for checked property if you want react re-render radio button.
Example:
<div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={this._handleInputChange}
value="1"
checked={this.state.radioButton1}
/>
True
</label>
</div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={this._handleInputChange}
value="0"
checked={this.state.radioButton2}
/>
False
</label>
</div>
</div>
You also set value for state like this (alternatively, you can initialize it with getInitialState):
this.setState({
radioButton1 : props.value ==="1",
radioButton2 :props.value ==="0"
});
And in _handleInputChange
function you're able to know that radio button is checked or unchecked by checking it's state.
_handleInputChange(e) {
var isChecked = e.target.value ==="1" ? this.state.radioButton1 : this.state.radioButton2;
this.props.handleChange(e);
}
Upvotes: 2
Reputation: 828
Thanks to some of the help here and on IRC I figured out it was a preventDefault
in my event handler. After removing that it worked perfectly!
Upvotes: 15
Reputation: 30676
use bind method to bind context this._handleInputChange.bind(this)
in the constructor,or use (e)=>this._handleInputChange(e)
on click ,when the event handler executed normally has no context.
or declared as this below,it can bind this automatically:
class ButtonGroup extends Component{
....
_handleInputChange= (e)=>{
...
}
sample below:
class ButtonGroup extends Component {
render() {
return (
<div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={(e) => this._handleInputChange(e)}
value="1"
checked={this.props.value === "1"}
/>
True
</label>
</div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={(e) => this._handleInputChange(e)}
value="0"
checked={this.props.value === "0"}
/>
False
</label>
</div>
</div>
);
}
_handleInputChange(e) {
this.props.handleChange(e);
}
}
class Form extends Component {
constructor(props) {
super(props);
this.state = {value: '1'};
}
render() {
var value = this.state.value;
return <ButtonGroup value={value} handleChange={(e) => this.valueChanged(e)}/>
}
valueChanged(e) {
this.setState({value: e.target.value});
}
}
ReactDOM.render(
<Form />,
document.getElementById('container')
);
Upvotes: 0