在 Redux 状态下更新单个值
Posted
技术标签:
【中文标题】在 Redux 状态下更新单个值【英文标题】:Update single value in Redux state 【发布时间】: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 中可以这样做吗?
【问题讨论】:
【参考方案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
会发生什么?是的,一直渲染。实际上,如果您更改属性,item
或 data
将完全更改。否则你如何通知 React 有变化? :)
注意:React 默认情况下不能根据值的变化进行更新。它更新的原因是因为您通过setState( ...data )
要求它。所以现在是关于粒度YOU如何控制调度(或渲染)的问题。人们可能会认为 React 在渲染方面很神奇,但实际上它只是在请求时才这样做。所以现在你的问题是,我要求它渲染,但它不应该渲染?哈哈,你明白了。
【讨论】:
以上是关于在 Redux 状态下更新单个值的主要内容,如果未能解决你的问题,请参考以下文章
React:Redux状态在一个效果中更新但在同一组件中的下一个效果是使用先前的state值
Redux (with React) Reducer switch 语句不更新状态