Как неизменяемо обновить объект, учитывая, что мы должны передать тот же объект, что и реквизит?

#javascript #reactjs #immutability #mutable

Вопрос:

У меня есть объект amounts , который обновляется при нажатии кнопки. И я передаю этот объект в качестве опоры другому компоненту. То, что я делаю прямо сейчас, — это обновление объекта изменяемым способом при событии нажатия кнопки.

 onClick = e => {
  amounts.map(
      amount => (amount.tax = taxes ? 500 : 0)
  );
}

<Display amounts={amounts} />
 

Как я могу обновлять суммы неизменяемым способом?

Комментарии:

1. Являются ли суммы массивом чисел? Кроме того, вы вызываете отображенное значение option , но затем используете его как amount — это опечатка или намеренно?

2. это массив объектов, и это была опечатка, я исправлю это

3. amounts.map создает новый массив, который никоим образом не используется. На самом деле вам нужно назначить его, чтобы он возымел эффект. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

4. Я понял твою точку зрения. Однако, поскольку суммы-это массив объектов, он обновлялся напрямую. Но, чтобы добиться неизменности, является ли это правильным решением xyz = amounts.map(.....) , а затем amounts = xyz

5. Кроме того, является onClick ли часть того же компонента, который выполняет рендеринг <Display /> ?

Ответ №1:

Как упоминалось в комментариях, происходит несколько вещей:

  1. Вы не обновляете amounts ссылку на массив, поэтому React не будет повторно отображаться на основе этой мутации.
  2. Вы используете Array#map для обновления одного свойства. Это приведет к обновлению ссылки на объект в коллекции сумм.
  3. Нет setAmounts или что-то подобное для обновления значения amount свойства в родительском компоненте.

Предполагая, что вы используете useState <Display /> родительский компонент s, вам придется передать setAmounts функцию <Display /> компоненту с помощью реквизита.

 <Display amounts={amounts} setAmounts={setAmounts} />
 
 onClick = e => {
  setAmounts(
    amounts.map(
      amount => ({ ...amount, tax: taxes ? 500 : 0 })
    );
  );
}