添加新项React时状态数组未正确更新?

时间:2018-07-23 20:16:54

标签: javascript reactjs

这是我的代码:

var questionsList = []

class PhotoDropZone extends Component {
  render() {
    return (
      <div id="dropZone">
        Drop a photo here.
      </div>
    );
  }
}

class Answers extends Component {

  constructor(props) {
    super(props);
    this.state = {
      answers: Array(4).fill(""),
      correctAnswers: [],
    };
    this.handleUpdate = this.handleUpdate.bind(this);
  }

  // let event = {
  //   index: 1,
  //   value: 'hello'
  // };
  handleUpdate (event) {
    //if ("1" == 1) // true
    //if ("1" === 1) //false 
    var answers = this.state.answers;
    answers[event.index] = event.value;
    this.setState(() => ({
      answers: answers
    }));

    console.log(event);
  }

  render () {
    return (
      <div id="answers">
                Answer Choices<br />
        {this.state.answers.map((value, index) => (
          <Answer value={value} key={index} onUpdate={this.handleUpdate} number={index}/>
        ))}
      </div>
    );
  }
}

class Answer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputText: "",
      answer: props.value,
      correctAnswers: "",
    };
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    const target = event.target;
    const value = target.type === "checkbox" ? target.checked : target.value;
    this.setState((previousState, props) => ({
      answer: value
    }));
    this.props.onUpdate({
      index: this.props.number,
      value
    });

    //
    // let sample = {
    //   kyle: "toast",
    //   cam: "pine"
    // };

    // sample.kyle
    // sample.cam

  }
  render () {
    return (
      <div>
        <input type="checkbox"/>
        <input type="text" value={this.state.answer} onChange={this.handleChange}/>
      </div>
    )
  }
}


var questionIdx = 0;

class Questions extends Component {
  constructor(props){
    super(props);
    this.state = {
      questions:[]
    }
    this.handleUpdate = this.handleUpdate.bind(this);
  }

  handleUpdate (event) {
    //if ("1" == 1) // true
    //if ("1" === 1) //false 
    var questions = this.state.questions
    questions[event.index] = event.value;
    this.setState(() => ({
      questions: questions
    }));

    console.log(event);
  }

  addQuestion = question => {
    questionIdx++;
    this.setState(prevState => ({
      questions: [...prevState.questions, question]
    }));
  };

  removeQuestion () {
    console.log("remove button");
  }

  render () {
    return (
      <div id="questions">
        <ol id="quesitonsList">
           {this.state.questions.map((value, index)=> (
            <li id={"questionLi" + uuid()}>
              {<Question onUpdate={this.handleUpdate} value={value} number={index}/>}
              {<RemoveQuestionButton onClick={this.removeQuestion}/>}
            </li>
          ))}
        </ol>
        <AddQuestionButton onClick={this.addQuestion} />
      </div>
    );
  }
}

class Question extends Component {
  constructor(props){
    super(props);
    this.state = {
      question: ""
    }
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    const target = event.target;
    const value = target.type === "checkbox" ? target.checked : target.value;
    this.setState((previousState, props) => ({
      question: value
    }));
      this.props.onUpdate({
        index: questionIdx,
        value
      });
  }

  render () {
    return (
      <div id={"questionDiv" + questionIdx}>
        Question<br />
        <input type="text" value={this.state.question} onChange={this.handleChange} />
        <PhotoDropZone />
        <Answers />
      </div>
    );
  }
}

class IntroFields extends Component {
  constructor (props) {
    super(props);
    this.state = {
      title: "",
      author: ""
    }
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    const target = event.target;
    const value = target.type === "checkbox" ? target.checked : target.value;
    const name = target.name;
    console.log([name]);
    this.setState((previousState, props) => ({
      [name]: value
    }));
  }

  render () {
    return (
      <div id="IntroFields">
        Title: <input type="text" value={this.state.title} onChange={this.handleChange} name="title"/>
        Author: <input type="text" value={this.state.author} onChange={this.handleChange} name="author"/>
      </div>
    );
  }
}

class AddQuestionButton extends Component {

  addQuestion = () => {
    this.props.onClick(
      <Question onUpdate={this.handleUpdate} value={this.value} number={this.index}/>
    );
  };

  render () {
    return (
      <div id="addQuestionButtonDiv">
        <button id="addQuestionButton" onClick={this.addQuestion}>Add Question</button>
      </div>
    );
  }
}

class RemoveQuestionButton extends Component {

  removeQuestion = () => {
    this.props.onClick(
      <Question onUpdate={this.handleUpdate} number={questionIdx}/>
    );
  }

  render () {
    return (
      <div id="removeQuestionButtonDiv">
        <button id="removeQuestionButton" onClick={this.removeQuestion}>Remove Question</button>
      </div>
    )
  }
}

class BuilderForm extends Component {
  render() {
    return (
      <div id="formDiv">
        <IntroFields />
        <Questions />
      </div>
    );
  }
}
export default BuilderForm;

因此,这是具有Add Question按钮的表单,该按钮将表单的整个部分添加到表单。我的questionsquestion状态有问题。当我添加初始问题并开始在Question输入中键入内容时,会添加另一部分(就像再次按下Add Question按钮一样),并且我注意到在{{1} }数组,另一个对象数组和我输入的字符串。每次单击questions按钮时,都会将另一对象数组内容添加到Add Question数组中,无论哪个“问题” ”输入后,字符串对象(在questions数组内部)将更新。理想情况下,表单的每个部分都将更新其自己的状态。

我不确定为什么会这样,因为我是React和JS的新手,所以即使对您的想法进行一点解释也会很有见地。

如果您需要更多解释,请告诉我,我会尽力解释。我已经尝试在CodePen和其他工具上使用它,但我从未成功过。提前谢谢。

更新:我能够获得it on CodeSandbox

1 个答案:

答案 0 :(得分:2)

questionIdx将比预期大1,因此使用时会创建一个新问题。

this.props.number组件的handleUpdate方法中使用Question

handleChange(event) {
  const target = event.target;
  const value = target.type === "checkbox" ? target.checked : target.value;
  this.setState({
    question: value
  });
  this.props.onUpdate({
    index: this.props.number,
    value
  });
}