【问题标题】:State Array not updating correctly when adding new item React?添加新项目 React 时状态数组未正确更新?
【发布时间】:2018-12-31 08:51:42
【问题描述】:

这是我的代码:

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 按钮的表单,该按钮将表单的整个部分添加到表单中。我的questions 和question 状态有问题。当我添加初始问题并开始输入我的Question 输入时,会添加另一个部分(就像再次按下Add Question 按钮一样),我注意到我的questions 数组中添加了两个项目,还有一个对象数组和我输入的字符串。每次单击Add Question 按钮时,都会将另一个对象数组添加到questions 数组中,我输入哪个“问题”输入并不重要,字符串对象( questions 数组内部)被更新。理想情况下,表单的每个部分都会更新自己的状态。

我不确定为什么会发生这种情况,我是 React 和 JS 的新手,所以即使对你认为发生的事情进行一点解释也会非常有见地。

如果您需要更多解释,请告诉我,我会尽力解释。我试图在 CodePen 和其他东西上得到这个,但我从来没有成功过。提前谢谢。

更新:我能够得到it on CodeSandbox

【问题讨论】:

  • 如果您将问题隔离在Minimal, Complete, and Verifiable example 中并创建例如一个说明它的CodeSandbox。
  • @Tholle 我能够在 CodeSandbox 上得到它,我用链接更新了我的问题
  • 就我所见,codesandbox 似乎很空。但是,通过阅读代码,您似乎改变了状态,而不是更新它。在您的handleUpdate 中检索状态,并添加一个新条目。理想情况下,可以创建一个新状态,然后更新新创建的数组
  • 该死,CodeSandbox 的东西一定不能正确保存,对此感到抱歉。谢谢你的建议,我会试试的
  • @Icepickle CodeSandbox 现在应该可以工作了

标签: javascript reactjs


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    • 2020-08-23
    • 2020-01-28
    • 2022-10-15
    • 2018-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多