在React.js中向数组添加对象

时间:2018-07-30 14:04:43

标签: reactjs

我知道这是一个简单的问题,但现在我正在为此苦苦挣扎。简而言之,我试图将新对象添加到从输入中获取的数组。这是渲染器内部的简单形式:

render() {
  return (
    <div className="container">
      <form onSubmit={this.handleSubmitTopic}>
        <input onChange={this.handleTopicName} placeholder="add topic name" /><br />
        <input onChange={this.handleQ1} type="text" placeholder="add question" /><br />
        <input onChange={this.handleQ2} type="text" placeholder="add question" /><br />
        <button>Save</button>
      </form>
    </div>
  );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

这是onChange句柄功能:

handleTopicName = (e) => {
    this.setState({ topicName: e.target.value });
  }

  handleQ1 = (e) => {
    const question = e.target.value;
    const qInput = {
      answer: 'no answer',
      question,
      questionId: uuid(),
    };
    const qArray = this.state.questions.slice();
    qArray.push(qInput);
    this.setState(prevState => ({ questions: qArray }));
  }

  handleQ2 = (e) => {
    const qInput = {
      answer: 'no answer',
      question: e.target.value,
      questionId: uuid(),
    };
    const qArray = this.state.questions.slice();
    qArray.push(qInput);
    this.setState(prevState => ({ questions: qArray }));
  }

  handleSubmitTopic = (e) => {
    e.preventDefault();
    this.props.onSaveTopic({
      topicName: this.state.topicName,
      questions: this.state.questions,
    });
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

最后是状态:

state = {
  topicName: '',
  questions: [],
}

我曾尝试用这样的传播算子添加对象

this.setState({questions: [...this.state.questions, {here goes question object}]})

每次提交结果后,我都会得到一个键入的每个字符的数组。

以下是结果的屏幕截图: enter image description here

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

使用onBlur事件代替onChange。 当焦点不在输入元素上时,将触发OnBlur。 当元素的值已更改时,将发生onChange事件。

render() {
  return (
    <div className="container">
      <form onSubmit={this.handleSubmitTopic}>
        <input onBlur={this.handleTopicName} placeholder="add topic name" /><br />
        <input onBlur={this.handleQ1} type="text" placeholder="add question" /><br />
        <input onBlur={this.handleQ2} type="text" placeholder="add question" /><br />
        <button>Save</button>
      </form>
    </div>
  );
}

答案 1 :(得分:0)

这是一个不同的答案,但这会大大改变您的代码逻辑。

class App extends React.Component {
  state = {
    topicName: '',
    inputs: {},
    questions: [],
  }

  handleTopicName = e =>
    this.setState({ topicName: e.target.value });


  handleInputs = (e) => {
    const { name, value } = e.target
    this.setState(prevState => ({ inputs: { ...prevState.inputs, [name]: value } }));
  }

  handleSubmitTopic = (e) => {
    e.preventDefault();
    const {inputs} = this.state;
    const questions = Object.keys(inputs).map( key => (
      {
        answer: 'no answer',
        question: inputs[key],
      //questionId: uuid(),
      }
    ));
    
    this.setState({ questions });

    /* this.setState( { questions }, () => 
      this.props.onSaveTopic( {
        topicName: this.state.topicName,
        questions,
      } )
     );*/
  }

  render() {
    console.log( this.state );
    return (
    <div className="container">
      <form onSubmit={this.handleSubmitTopic}>
        <input onChange={this.handleTopicName} placeholder="add topic name" /><br />
        <input name="q1" onChange={this.handleInputs} type="text" placeholder="add question" /><br />
        <input name="q2" onChange={this.handleInputs} type="text" placeholder="add question" /><br />
        <button>Save</button>
      </form>
    </div>
  );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

我创建了一个函数来处理输入:handleInputs。此函数使用其name属性处理两个输入。因此,我们正在使用这些输入来创建questions。这是在handleSubmitTopic函数中完成的。

在这里,我们使用inputs对象将其映射到新的questions数组中。在工作代码中,我只是设置了questions状态。多亏了该片段的作品。如果您将其注释掉并使用您的版本,则可以使用onSaveTopic。在这里,在设置questions状态之后,在setState回调函数中,由于setState是异步的,我们正在执行此操作。

此外,console.log方法中有一个render,以查看发生了什么事。