web-dev-qa-db-ja.com

Reduxの特定の配列項目内の単一の値を更新する方法

状態を再レンダリングするとUIの問題が発生する問題があり、ページ上の再レンダリングの量を減らすために、reduce内の特定の値のみを更新するよう提案されました。

これは私の状態の例です

{
 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は、新しい値を含む配列全体です。しかし、実際には、contents配列の2番目の項目のテキストを更新するだけでよく、このようなものは機能しません

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

ここで、action.payloadは、更新に必要なテキストです。

75
Ilja

React Immutability helpers を使用できます

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

mapを使用できます。以下に実装例を示します。

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

すべてを1行で行う必要はありません。

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

私の場合、ルイスの答えに基づいて、次のようなことをしました。

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

...Reducer's 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,
  },
};

1
Erfan226

パーティーに非常に遅れましたが、すべてのインデックス値で機能する一般的なソリューションがあります。

  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)
         ]
    }
1
Ivan V.

Redux状態でこの種の操作が必要な場合、スプレッド演算子はあなたの友人であり、このプリンシパルはすべての子供に適用されます。

これがあなたの状態であるふりをしましょう:

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

そして、あなたはRavenclawに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's properties
        points: state.houses[key].points + 3   // update its `points` property
      }
    }
  }

スプレッド演算子を使用することで、新しい状態のみを更新し、他のすべてをそのまま残すことができます。

これからの例 驚くべき記事 、あなたは素晴らしい例でほとんどすべての可能なオプションを見つけることができます。

0
Luis Rodriguez