True and false radio buttons in react
I think that there are a few structural problems. It's hard to tell without a bin, but here's what I see...
First, you're mixing uncontrolled components with controlled methods. E.g., you're not setting the checked attribute on the radio buttons (controlled), but you're also not checking the refs (or setting them) for values (uncontrolled). There should be a checked attribute for controlled.
Second, there's a lot of string to boolean mismatching. Assuming true and false are the only values for these buttons, try:
const isPublished = event.currentTarget.value === 'true' ? true: false;
I put it together in a pen.
https://codepen.io/anon/pen/pNooXq?editors=0010
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
sample: '',
description: '',
isPublished: null,
};
this._handleRadio = this._handleRadio.bind(this);
this._handleSubmit = this._handleSubmit.bind(this);
}
_handleRadio(event) {
const isPublished = event.currentTarget.value === 'true' ? true: false;
console.log('handle', isPublished);
this.setState({ isPublished });
}
_handleSubmit(event) {
event.preventDefault();
event.stopPropagation();
const sampleObj = this.state;
console.log(sampleObj);
}
render() {
const { isPublished } = this.state;
console.log(isPublished, true);
return (
<form onSubmit={this._handleSubmit}>
<div className="radio">
<label>
<input
type="radio"
name="isPublished"
value="true"
checked={isPublished === true}
onChange={this._handleRadio} />
Yes
</label>
</div>
<div className="radio">
<label>
<input
type="radio"
name="isPublished"
value="false"
checked={isPublished === false}
onChange={this._handleRadio} />
No
</label>
</div>
<button type="submit">Submit</button>
</form>
);
}
}
Related videos on Youtube
Munsterberg
Updated on June 04, 2022Comments
-
Munsterberg almost 2 years
Here is my current code:
The state in my component
this.state = { name: '', sample: '', description: '', isPublished: null, };
Here is the handler for the radio buttons
_handleRadio(event) { let value = true; if (typeof event.currentTarget.value === 'string') { (event.currentTarget.value === 'true' ? value = true : value = false ); } this.setState({isPublished: value}); }
And finally here are my radio buttons
<div className="radio"> <label><input type="radio" name="isPublished" value="true" onChange={this._handleRadio} />Yes</label> </div> <div className="radio"> <label><input type="radio" name="isPublished" value="false" onChange={this._handleRadio} />No</label> </div>
Sorry for the poor formatting, copy and pasting my code over here didn't turn out so well. When I try to fix it, I mess it up even more.
So right now, as is, the state is being changed, which is exactly what I want. But when I submit and make the POST request to my api, the isPublished state returns to true.
Here is my submit handler
_handleSubmit(event) { event.preventDefault(); event.stopPropagation(); const sampleObj = this.state; console.log(sampleObj); api.post('samples', sampleObj).done((result) => { console.log('Sample Saved!'); this.context.router.push(`${result.id}/`); }).fail((error) => { console.log('failed'); console.log(error); }); }
Why does the state of isPublished return to true during the submit, even after changing it to false?
-
Justin Herter over 7 yearsI have a feeling your if block in _handleRadio method is the culprit, try adding a console.log() in there to see if it is being hit and you are getting the proper value form your selection.
-
Munsterberg over 7 years@JustinHerter just tried it, everything seems to be firing. I thought the same thing at first
-
Justin Herter over 7 yearsUse the callback method of setState to check the value of isPublished after setting it, like this this.setState({isPublished: value}, function () { console.log("state: ", this.state)}); lets just make sure things are being set as we would expect then move on with the debugging.
-
Munsterberg over 7 yearsGood idea. Yeah its definitely logging the correct value. Even the console.log(sampleObj) returns the value, its not until grabbing the object after the redirect does the value change back to true.
-
Justin Herter over 7 yearsIs the _handleRadio method being fired on route change? Check your logs.
-
Munsterberg over 7 yearsWhere can I go to check that? @JustinHerter because I dont believe it is
-
Justin Herter over 7 yearsOh sorry just console.log at the top of the method and check after you submit. in fact console log everywhere and watch it as you step through the process. Unfortunately you will have to do the debugging =). Something is happening around the submission event either just prior, during, or after so just log everywhere and watch to see what is happening. Good luck.
-
Munsterberg over 7 yearsThanks! After the console.logs i can see its happening after the submit, just not sure why. Im gonna keep digging away at it :), thanks for the tips!
-
D. Walsh over 7 yearsSo
sampleObj
gives the correct value from state, but the received payload from api.post shows an incorrect value? -
Munsterberg over 7 yearsYeah sampleObj gives the correct value, but when I grab it with a get request using the id in another component, it returns to false. So sampleObj is definitely being sent with the correct data (and the false value for isPublished), but when I get the same entry from the api, isPublished is true @D.Walsh
-
D. Walsh over 7 yearsWait, using what id? And from what component?
-
Munsterberg over 7 yearsso this
this.context.router.push(
${result.id}/);
renders another component which calls the following:api.getJSON(
samples/${this.props.params.id}) .done((result) => { console.log(result); this.setState({sample: result}); });
not really sure how to format in the comments
-
-
Munsterberg over 7 yearsThis works great, but the real issue was in the API I was hitting. After doing some digging in their docs, I found it. Thanks for explaining the controlled vs uncontrolled though, needed that as I am fairly new to react
-
D. Walsh over 7 yearsThanks, glad it helped!