Подтвердить что ты не робот

Как обновить одно значение внутри определенного элемента массива в сокращении

У меня проблема, когда повторная передача состояния вызывает проблемы ui, и было предложено только обновить определенное значение внутри моего редуктора, чтобы уменьшить количество повторного рендеринга на странице.

это пример моего состояния

{
 name: "some name",
 subtitle: "some subtitle",
 contents: [
   {title: "some title", text: "some text"},
   {title: "some other title", text: "some other text"}
 ]
}

и в настоящее время я обновляю его так

case 'SOME_ACTION':
   return { ...state, contents: action.payload }

где action.payload - это целый массив, содержащий новые значения. Но теперь мне просто нужно обновить текст второго элемента в массиве содержимого, и что-то вроде этого не работает.

case 'SOME_ACTION':
   return { ...state, contents[1].text: action.payload }

где action.payload теперь текст, который мне нужен для обновления.

4b9b3361

Ответ 1

Вы можете использовать Помогать помощникам по невосприимчивости

import update from 'react-addons-update';

// ...    

case 'SOME_ACTION':
  return update(state, { 
    contents: { 
      1: {
        text: {$set: action.payload}
      }
    }
  });

Хотя я бы предположил, что вы, вероятно, будете делать что-то более похожее на это?

case 'SOME_ACTION':
  return update(state, { 
    contents: { 
      [action.id]: {
        text: {$set: action.payload}
      }
    }
  });

Ответ 2

Вы можете использовать map. Вот пример реализации:

case 'SOME_ACTION':
   return { 
       ...state, 
       contents: state.contents.map(
           (content, i) => i === 1 ? {...content, text: action.payload}
                                   : content
       )
    }

Ответ 3

Вам не нужно делать все в одной строке:

case 'SOME_ACTION':
  const newState = { ...state };
  newState.contents = 
    [
      newState.contents[0],
      {title: newState.contnets[1].title, text: action.payload}
    ];
  return newState

Ответ 4

Очень поздно для вечеринки, но вот общее решение, которое работает с каждым значением индекса.

  1. Вы создаете и распространяете новый массив от старого массива до index который хотите изменить.

  2. Добавьте данные, которые вы хотите.

  3. Создать и распространить новый массив из index вы хотите изменить, до конца массива

let index=1;// probabbly action.payload.id
case 'SOME_ACTION':
   return { 
       ...state, 
       contents: [
          ...state.contents.slice(0,index),
          {title: "some other title", text: "some other text"},
         ...state.contents.slice(index+1)
         ]
    }

Ответ 5

В моем случае я сделал что-то подобное, основываясь на ответе Луиса:

...State object...
userInfo = {
name: '...',
...
}

...Reducer code...
case CHANGED_INFO:
return {
  ...state,
  userInfo: {
    ...state.userInfo,
    // I'm sending the arguments like this: changeInfo({ id: e.target.id, value: e.target.value }) and use them as below in reducer!
    [action.data.id]: action.data.value,
  },
};

Ответ 6

Я считаю, что когда вам нужны такие операции в вашем состоянии Redux, оператор распространения - ваш друг, и этот принцип применим ко всем детям.

Давайте представим, что это ваше государство

const state = {
    houses: {
        gryffindor: {
          points: 15
        },
        ravenclaw: {
          points: 18
        },
        hufflepuff: {
          points: 7
        },
        slytherin: {
          points: 5
        }
    }
}

И вы хотите добавить 3 очка в Равенкло

const key = "ravenclaw";
  return {
    ...state, // copy state
    houses: {
      ...state.houses, // copy houses
      [key]: {  // update one specific house (using Computed Property syntax)
        ...state.houses[key],  // copy that specific house properties
        points: state.houses[key].points + 3   // update its 'points' property
      }
    }
  }

Используя оператор распространения, вы можете обновить только новое состояние, оставив все остальное без изменений.

Пример взят из этой удивительной статьи, вы можете найти практически все возможные варианты с отличными примерами.