Reactjs 处理输入数组的onChange和设置状态

Reactjs 处理输入数组的onChange和设置状态,reactjs,Reactjs,只是一点背景知识,我对javascript和web开发还很陌生,但我一直很喜欢做一些关于React的教程。也是我第一次在stackoverflow上发帖 我正在构建一个组件来显示是/否问题的列表,用户必须通过选择单选按钮并在文本区域中选择性地添加一些注释来做出响应。我不确定如何为使用map生成的输入数组设置状态 我有一系列问题: var questions = [ {id:"1", text:"Is the source up to date?"}, {id:"2", text:

只是一点背景知识,我对javascript和web开发还很陌生,但我一直很喜欢做一些关于React的教程。也是我第一次在stackoverflow上发帖

我正在构建一个组件来显示是/否问题的列表,用户必须通过选择单选按钮并在文本区域中选择性地添加一些注释来做出响应。我不确定如何为使用map生成的输入数组设置状态

我有一系列问题:

var questions = [
    {id:"1", text:"Is the source up to date?"},
    {id:"2", text:"Question 2 placeholder"},
    {id:"3", text:"Question 3 placeholder"},
]
这是我的(未完成的)部分:

var QuestionList = React.createClass({
    getInitialState: function () {
        return {
            commentText: "",
        }
    },

    onUpdateComments: function (e) {
        this.setState({
            commentText: e.target.value
        });
    },
    render: function () {
        var QuestionLines = this.props.questions.map(function(question) {
            return (
                <div key={question.id}>
                    <div>
                        <div>
                            {question.text}
                        </div>
                        <label>
                            <input type="radio" name={question.id} value = {question.id+'Y'}/>Yes
                        </label>
                        <label>
                            <input type="radio" name={question.id} value = {question.id+'N'}/>No
                        </label>
                    </div>
                    <div>
                        <textarea 
                            name = {question.id}
                            onChange = {this.onUpdateComments}
                            placeholder="Enter comments here" 
                            value={this.state.commentText} />
                    </div>
                </div>
            );
        }, this);
        return (
            <div>
                {QuestionLines}
            </div>
        )
    }
});
var QuestionList=React.createClass({
getInitialState:函数(){
返回{
评论全文:“,
}
},
onUpdate注释:函数(e){
这是我的国家({
注释文本:e.target.value
});
},
渲染:函数(){
var QuestionLines=this.props.questions.map(函数(问题){
返回(
{问题.文本}
对
不
);
},这个);
返回(
{问题行}
)
}
});
应用程序现在在所有3个textarea中显示相同的文本,我可以看到这是因为我将对textarea的所有更改存储在相同的commmentText状态中。然而,我真的很困惑,我需要做什么来分离这些,并使这项工作。任何帮助都将不胜感激

此外,正如我所提到的,我对这一点非常陌生,所以如果我如何构建我的组件有任何问题,请让我知道


谢谢

只需将
commentText
设置为对象:

var QuestionList = React.createClass({
    getInitialState: function () {
        return {
            commentText: {},
        }
    },

    onUpdateComments: function (e) {

        // Note that e.target.name is question.id
        var target = e.target;
        this.state.commentText[target.name] = target.value;
        this.forceUpdate();
    },
    render: function () {
        var QuestionLines = this.props.questions.map(function(question) {

            var id = question.id; // store id

            return (
                <div key={id}>
                    <div>
                        <div>
                            {question.text}
                        </div>
                        <label>
                            <input type="radio" name={id} value = {id+'Y'}/>Yes
                        </label>
                        <label>
                            <input type="radio" name={id} value = {id+'N'}/>No
                        </label>
                    </div>
                    <div>
                        <textarea 
                            name = {id}
                            onChange = {this.onUpdateComments}
                            placeholder="Enter comments here" 
                            value={this.state.commentText[id]} />
                    </div>
                </div>
            );
        }, this);
        return (
            <div>
                {QuestionLines}
            </div>
        )
    }
});

一种解决方案是使用commentTextStore对象,其中键(属性)是commentId,然后让每个问题文本区域写入commentId对应的值

我会这样做:

onUpdateComments: function (e) {

    // Note that e.target.name is question.id
    var target = e.target;
    this.setState(function(previousState) {
      return {
        commentText: {
          ...previousState.commentText, 
          [target.name]: target.value
        }
      }
    });
},
var QuestionList = React.createClass({
    getInitialState: function () {
        return { comments: {} } //set internal state comment as an empty object
    },

    onUpdateComments: function (id, e) {

        /*
            you can modify your state only using setState. But be carefull when trying to grab actual state and modify it's reference.
            So, the best way is to create a new object (immutable pattern), and one way of doing that is to use Object.assign
        */
        var comments = Object.assign({}, this.state.comments);

        /* set, for instance, comment[1] to "some text" */
        comments[id] = e.target.value;

        /* set the state to the new variable */
        this.setState({comments: comments});


    },
    render: function () {
        var QuestionLines = this.props.questions.map(function(question) {

            /* grab the comment for this ID. If undefined, set to empty */
            var comment = this.state.comments[question.id] || "";

            return (
                <div key={question.id}>
                    <div>
                        <div>
                            {question.text}
                        </div>
                        <label>
                            <input type="radio" name={question.id} value = {question.id+'Y'}/>Yes
                        </label>
                        <label>
                            <input type="radio" name={question.id} value = {question.id+'N'}/>No
                        </label>
                    </div>
                    <div>
                        <textarea 
                            name = {question.id}
                            onChange = {this.onUpdateComments.bind(this,question.id)}
                            placeholder="Enter comments here" 
                            value={comment} />
                    </div>
                </div>
            );
        }, this);
        return (
            <div>
                {QuestionLines}
            </div>
        )
    }
});
var QuestionList=React.createClass({
getInitialState:函数(){
返回{comments:{}//将内部状态注释设置为空对象
},
onUpdate注释:函数(id,e){
/*
您只能使用setState修改您的状态。但在尝试获取实际状态并修改其引用时请小心。
因此,最好的方法是创建一个新对象(不可变模式),其中一种方法是使用object.assign
*/
var comments=Object.assign({},this.state.comments);
/*例如,将注释[1]设置为“某些文本”*/
注释[id]=e.target.value;
/*将状态设置为新变量*/
this.setState({comments:comments});
},
渲染:函数(){
var QuestionLines=this.props.questions.map(函数(问题){
/*获取此ID的注释。如果未定义,则设置为空*/
var comment=this.state.comments[question.id]| |“”;
返回(
{问题.文本}
对
不
);
},这个);
返回(
{问题行}
)
}
});

正是我想要的。谢谢