如何更新状态中的特定数组元素?

时间:2017-12-20 20:40:04

标签: javascript reactjs

我有州:

this.state = {
  count: 1,
  currentKey: '1',
  form: [{ cost: '', amount: '1', key: 1 }]
}

我需要更新成本而不需要更改其他元素

我试着这样做:

this.setState(prevState => ({
  form: [
    {
      cost: e,
      amount: prevState.form[this.state.currentKey - 1].amount,
      key: prevState.form[this.state.currentKey - 1].key
    }
  ]
}))

但它得到TypeError:无法读取未定义的属性'amount'。

2 个答案:

答案 0 :(得分:0)

也许更简单的方法:定义成本,然后设置状态。

const cost = (+this.state.currentKey + 1).toString();
this.setState({
  ...this.state,
  form: [{ ...this.state.form[0], cost }]
});

<强> New row doesn't show

答案 1 :(得分:0)

每次都覆盖form数组 您需要映射数组并仅更改所需的对象,我猜它是根据您所在州的currentKey属性。
你应该做点什么:

form.map((f) => {
  if (f.key !== currentKey) return f;
    return {
      ...f,
      cost: newCost
   }
});

这是一个完整运行的示例,我添加了一些按钮和输入,以便您可以添加表单并更改每个表单的cost(在更改之前不要忘记选择表单!)。

class Form extends React.Component {

  onFormSelect = () => {
    const { onFormSelect, formKey } = this.props;
    onFormSelect(formKey);
  }

  render() {
    const { index, formKey, cost, amount, active } = this.props;
    return (
      <div className={`form ${active && "active"}`} onClick={this.onFormSelect}>
        <div>{`Form - #${index}`}</div>
        <div>{`key - ${formKey}`}</div>
        <div>{`cost - ${cost}`}</div>
        <div>{`amount - ${amount}`}</div>
        <hr />
      </div>
    );
  }
}


class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 1,
      currentKey: '1',
      form: [{ cost: '', amount: '1', key: 1 }],
      newCost: ''
    }
  }

  addForm = () => {
    const { form } = this.state;
    const newCount = form.length + 1;
    const newForm = { cost: '', amount: '', key: newCount };
    this.setState({
      count: newCount,
      form: [
        ...form,
        newForm
      ]
    })
  }

  onFormSelect = formId => {
    this.setState({
      currentKey: formId
    })
  }

  onNewCostChange = ({ target }) => this.setState({ newCost: target.value });

  onNewCostsubmit = () => {
    const { form, currentKey, newCost } = this.state;
    const nextForm = form.map((f) => {
      if (f.key !== currentKey) return f;
      return {
        ...f,
        cost: newCost
      }
    });

    this.setState({ form: nextForm });
  }

  render() {
    const { form, count, currentKey, newCost } = this.state;
    return (
      <div>
        <div>
          <span>{`count: ${count} --- current key: ${currentKey} `}</span>
          <button onClick={this.addForm}>Add form</button>
          <div>
            <input
              type="text"
              value={newCost}
              placeholder="set cost"
              onChange={this.onNewCostChange}
            />
            <button onClick={this.onNewCostsubmit}>Submit</button>
          </div>
        </div>
        <hr />
        {
          form.map((f, i) => {
            return (
              <Form
                key={i}
                formKey={f.key}
                active={f.key === currentKey}
                index={i}
                amount={f.amount}
                cost={f.cost}
                onFormSelect={this.onFormSelect}
              />
            );
          })
        }
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
.form{
  cursor: pointer;
  padding: 10px;
}

.active{
  background-color: #333;
  color: #fff;
}
<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>