【问题标题】:Update single value in Redux state在 Redux 状态下更新单个值
【发布时间】:2021-12-24 05:36:27
【问题描述】:

我有一个页面,上面有几个组件,其中一个组件读取 redux 状态。 当 redux 对象组件发生一些变化时,它会重新加载,显示微调器并且组件上的所有数据都会更新。 但我的任务是更新 redux 对象状态中的一个值,而无需重新渲染和刷新所有内容。 例如这里是 redux 对象,它包含一个包含一些数据的对象数组。 我需要在某个对象中更新一个值state,比如说最后一个。 但我需要这样做,而不必更新所有状态。

state:{
 0:{
  name : 'some name.....',
  surname: 'some surname',
  age: '23',
  phone: '+12345678'
  state: 'ON' 
 },

 1:{
  name : 'some name.....',
  surname: 'some surname',
  age: '23',
  phone: '+12345678'
  state: 'ON' 
 },

 2:{
  name : 'some name.....',
  surname: 'some surname',
  age: '23',
  phone: '+12345678'
  state: 'OFF' <-- I need to update only this one 
 },

}

我在 Redux 操作中有一个函数可以加载所有这些数据。

但现在我需要一个单独的函数 updateData 之类的函数,它将更新现有状态对象中的一个值,而无需刷新所有内容。

在 Redux 中可以这样做吗?

【问题讨论】:

    标签: reactjs redux react-redux redux-store redux-storage


    【解决方案1】:

    您需要熟悉 Redux 中 action 和 reducer 的工作方式,但是是的,这绝对是可能的。

    您可以创建一个UPDATE_DATA 动作创建器,您可以在您的反应组件中调用它。您将拥有一个 reducer 来控制数据的处理方式和状态更改方式。

    -编辑- 如 cmets 中所述,我在 Redux 的减速器中使用“immer”。这是我如何使用它来编辑和现有数组中的项目的示例:

    case EDIT_ITEM:
          return produce(state, (draft) => {
            const index = findItemIndex(draft, action.payload._id)
            draft[index] = action.payload
          })
    

    所以你传入状态和回调,草稿是状态对象的可变等价物。

    【讨论】:

    • 这是问题所在,如果可能的话,我真的不明白减速器应该是什么样子。假设我在减速器中有动作来加载数据。 case LOAD_ALL_USERS_SUCCES: return { ...state, usersLoading: false, users: action.payload.response.users, } 当我想更新它时。我在操作中使用 getState() 获取现有状态并更改属性它在减速器中应该是什么样子,所以它不会更新组件中的所有内容?
    • Redux 中的状态是不可变的。我在最近的一个应用程序中使用了一个名为“immer”的模块,它提供了一个名为produce() 的函数。这为处理数据提供了灵活性,就好像它不是一成不变的一样。 immerjs.github.io/immer
    • 我在答案中添加了一个示例。
    【解决方案2】:

    您的状态是对象的对象(不是数组)。 您无法更新您所在州的单个属性。您必须提供具有更新值的新对象。研究 redux 中的不变性:https://redux.js.org/faq/immutable-data

    在你的 reducer 中试试这个:

    const changedVal=state[2];
    changedVal.state='ON';
    return {...state,changedVal};
    

    【讨论】:

      【解决方案3】:

      简而言之,更新一个属性实际上是不可能的。当然做不到,但是难度很大。我可以解释原因。

      让我们从更新项目开始。这绝对是可能的。假设您有一个 redux 选择器在将数据发送到组件时监听 data

        const DisplayOneItem = React.memo(( name, age ) => { ... })
      

      您可以看到,首先将name(和age)发送到该组件,然后应用React.memo,这样只有当其中一个属性发生更改时,它才能更新。但不要与以下行混为一谈:

        const DisplayOneItem = React.memo(( item ) => { ... })
      

      上面的行占用了整个item,当你改变一个属性时,item也会改变,因此无论如何,你都会得到一个新的更新。

      您可能想知道如果不使用React.memo 会发生什么?是的,一直渲染。实际上,如果您更改属性,itemdata 将完全更改。否则你如何通知 React 有变化? :)

      注意:React 默认情况下不能根据值的变化进行更新。它更新的原因是因为您通过setState({ ...data }) 要求它。所以现在是关于粒度YOU如何控制调度(或渲染)的问题。人们可能会认为 React 在渲染方面很神奇,但实际上它只是在请求时才这样做。所以现在你的问题是,我要求它渲染,但它不应该渲染?哈哈,你明白了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-19
        • 1970-01-01
        • 1970-01-01
        • 2018-06-29
        相关资源
        最近更新 更多