多次出现带有单选按钮的渲染组件问题

Having issue rendering components with radio buttons multiple times

先了解一下背景,我正在做一份问卷并决定开始学习 React.js。问卷的每个步骤都包括一个问题和一个 yes/no 单选按钮组,以及导航按钮。这是 jsfiddle。问题组件非常简单,我在父组件中将 formData 和保存数据函数传递给它。

以及问题部分的代码

var Question = React.createClass({
    getInitialState: function() {
        return {
        }
    },
    createMarkup: function(html) {
        return {
            __html: html
        };
    },

    render: function() {
        var subtitle = this.props.subtitle || '';
        var name = this.props.name;
        if (this.props.formData[name] === undefined) {
            var answer_yes = null;
            var answer_no = null;
        } else {
            answer_yes = this.props.formData[name] == "yes" ? true : null;
            answer_no = this.props.formData[name] == "no" ? true : null;
        }
        console.log(answer_yes);
        console.log(answer_no);
        return (
            <div className="container-question">
                <label className="default" dangerouslySetInnerHTML={this.createMarkup(this.props.question)}></label>
                <span className="alert subtitle" dangerouslySetInnerHTML={this.createMarkup(subtitle)}></span>
                <div className="form-group form-group-radio">
                    <div className="row">
                        <div className="col-xs-4">
                            <input type="radio" id={name + "_yes"} name={name} value="yes" defaultChecked={answer_yes} onChange={this.props.saveData}/><label htmlFor="yes">Yes</label><br></br>
                            <input type="radio" id={name + "_no"} name={name} value="no" defaultChecked={answer_no} onChange={this.props.saveData}/><label htmlFor="no">No</label>
                        </div>
                    </div>
                </div>
            </div>
        );
    }
});

问题是,当您 select 您对第一个问题的回答并点击下一步时,第二个问题的无线电控制随之改变,当您先回答第二个问题时也会发生同样的事情。我将 defaultChecked 的布尔变量存储为渲染函数中的局部变量,并将它们记录在控制台中。

我犯了什么明显的错误吗?感谢您的帮助。

这是一个更新后的 jsfiddle:https://jsfiddle.net/69z2wepo/8365/

问题是您在 React 中使用了所谓的 'uncontrolled component'。有关详细信息,请参阅此页面:https://facebook.github.io/react/docs/forms.html

为您的场景更改为受控组件意味着使用 checked 而不是 defaultCheckeddefaultChecked 适用于不受控制的组件,其中输入控件(在您的情况下为单选按钮)的值不受组件的 propsrender 方法控制。 React 的真正设计目的是使用受控组件,其中 props/state/render 完全驱动 UI 显示的内容。

从使用 defaultChecked 更改为 checked 时,您会注意到的第一件事是您将无法再更改 UI 中的无线电状态。发生这种情况的原因是因为虽然您的应用程序状态在您的 saveData 函数中被更改,但您的组件没有被重新渲染。

有几种不同的方法来处理这个问题。更新后的 jsfiddle 正在 saveData 期间重新呈现您的应用程序。理想情况下,这应该以不同的方式考虑。 saveData 应该从父组件中移出并进入 FormDataStore 概念(参见 React Flux 架构,https://facebook.github.io/flux/docs/overview.html)或者父组件应该拥有 formData 状态和在 saveData 中调用 setState 自身,这将导致重新渲染 DOM 树的那部分。