最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React controlled radio buttons not being checked - Stack Overflow

programmeradmin3浏览0评论

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.

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.

Share Improve this question asked Feb 28, 2017 at 3:10 MunsterbergMunsterberg 8284 gold badges18 silver badges38 bronze badges 3
  • 3 maybe you need to use defaultChecked instead of checked – A. L Commented Feb 28, 2017 at 3:34
  • @A.L I think you should write that as an answer. It solved the issue I was having. – Wylie Commented Jul 21, 2021 at 14:22
  • @A.L Can you add more context as in why defaultChecked works while checked not? It solved my issue as well but I am confused and wanna know exactly why is this happening. – Mohammad Jawad Barati Commented Oct 17, 2024 at 23:04
Add a comment  | 

3 Answers 3

Reset to default 15

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!

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

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')
        );
发布评论

评论列表(0)

  1. 暂无评论