如何更改React组件的特定实例上的数据?

时间:2016-10-04 00:30:38

标签: reactjs

如何更新组件特定实例的数据?现在我的addOption函数正在将元素推送到每个实例的options数组,而实际上我只是想让它更新我点击的特定实例。因此,当我运行option方法时,它会为每个question组件呈现addOption个组件。谢谢!

// Quiz Builder Form

import React from 'react';
import Question from './Question';
import firebase from 'firebase';

const QuizBuilderForm = React.createClass({
    getInitialState: function() {
        return {
            questions: []
        };
    },
    addQuestion: function(id) {
        var questions = this.state.questions; 
        questions.push({ qtext : "", options: [""], id: this.state.questions.length, answer: "" });
        this.setState({
            questions: questions
        });
    },
    addOption: function(index) {
        var questions = this.state.questions;
        for (index = 0; index < questions.length; index++) {
            questions[index].options.push("");
        }
        this.setState({
            questions: questions
        })
    },
    handleSubmit: function(event) {
        event.preventDefault();
        console.log(this.state.questions);
        this.firebaseRef = firebase.database().ref('quizzes');
        this.firebaseRef.push({
            question: this.state.questions
        });
        this.refs.form.reset();
        this.setState({
            question: [{ qtext : "", options:[""], id: 0, answer: ""}]
        });
    },
    handleChange: function(event) {
        // Do something
    },
    componentDidMount: function() {
        this.addQuestion();
    },
    render: function() {
        var questions = this.state.questions.map((question, index) => <Question key={index} index={index} ref={'question: ' + index} question={question} addOption={this.addOption} handleChange={this.handleChange} {...this.props}/>);
        return (
            <form className="quiz-form" onSubmit={this.handleSubmit} ref="form">
                {questions}
                <button type="button" className="add-question" onClick={this.addQuestion} disabled={this.state.questions.length === 5}>{this.state.questions.length < 5 ? 'Add another question' : 'Question limit reached!'}</button>
                <button type="submit">Create Quiz</button>
            </form>      
        );
    }
});

export default QuizBuilderForm;

// Question component 

import React from 'react';
import Option from './Option';

const Question = React.createClass({
    render: function() {
        var options = this.props.question['options'].map((option, index) => <Option key={index} index={index} option={option}/>);
        return (
            <div className="question">
                <input type="text" value="" onChange={this.props.handleChange}></input>
                {options}
                <button type="button" onClick={this.props.addOption}>Add another option</button>
            </div>
        );
    }
});

export default Question;

// Option component 

import React from 'react';

const Option = React.createClass({
    render: function() {
        return (
            <input type="text" value="" placeholder="Enter an answer here"></input>        
        );
   }
});

export default Option;

1 个答案:

答案 0 :(得分:1)

好吧,在您的addOption(index)方法中,您没有使用index更新您想要的问题,因为在for循环中,它会遍历所有问题并添加他们的选择。

我认为这样的事情会起作用:

  addOption: function(index) {
    var questions = this.state.questions,
        question = questions[index];

    question = Object.assign({}, question, {options: question.options.concat('')});

    questions = questions
                  .slice(0, index)
                  .concat([question])
                  .concat(questions.slice(index + 1));

    this.setState({
        questions: questions
    })
},

并在<Question />组件中更改此内容:

const Question = React.createClass({
  addOption: function () {
    this.props.addOption(this.props.index);
  },
  render: function() {
    var options = this.props.question['options'].map((option, index) => <Option key={index} index={index} option={option}/>);
    return (
        <div className="question">
            <input type="text" value="" onChange={this.props.handleChange}></input>
            {options}
            <button type="button" onClick={this.addOption}>Add another option</button>
        </div>
    );
  }
});

addOptions()组件的<QuizBuilderForm />,您收到了event参数,但是您希望收到所点击问题的index。因此,为了做到这一点,您可以在<Question />中创建一个方法来处理按钮事件,并使用正确的参数调用this.props.addOption()

尽量避免会改变状态的函数,这就是我使用Object.assign()Array.slice()Array.concat()的原因(ES6 +扩展运算符比数组和对象更容易一些) ,所以你可以写question = {...question, { options: [...question.options, ''])。