Redux reducer,检查状态数组中是不是存在值并更新状态
Posted
技术标签:
【中文标题】Redux reducer,检查状态数组中是不是存在值并更新状态【英文标题】:Redux reducer, check if value exists in state array and update stateRedux reducer,检查状态数组中是否存在值并更新状态 【发布时间】:2016-06-17 18:50:35 【问题描述】:所以我有一个数组chosenIds[]
,它基本上包含一个ids (numbers)
的列表。但我无法访问减速器中的状态以检查 ID I parsed to my action
是否在数组中。
const initialState =
'shouldReload': false,
'chosenIds': [],
;
export default function filter(state = initialState, action)
switch (action.type)
case ADD_TYPE:
console.log(state.chosenIds, "Returns undefined???!!!");
// Check if NUMBER parsed is in state
let i = state.chosenIds.indexOf(action.chosenId);
//If in state then remove it
if(i)
state.chosenIds.splice(i, 1);
return
...state.chosenIds,
...state.chosenIds
// If number not in state then add it
else
state.chosenIds.push(action.chosenId)
return ...state.chosenIds, ...state.chosenIds
我不确定发生了什么...但是当我登录state.chosenIds
时,它返回未定义?它甚至不返回初始的空数组 []
。
基本上这个函数要做的是检查action.chosenId
是否在state.chosenIds
中,如果是,则删除action.chosenId
值,如果不是,则将action.chosenId
添加到国家。
【问题讨论】:
这意味着它已经通过了一个状态,但该状态不包含键“chosenIds”。你能告诉我们你是如何调度动作的吗? 状态对象的其余部分是什么样的? 【参考方案1】:我在这里看到了一些不同的问题。
首先,您在已处于该状态的阵列上使用splice()
和push()
。那是直接突变,它破坏了 Redux。您需要制作数组的副本,然后修改该副本。
其次,对象传播的使用看起来不正确。您正在使用它,就好像“chosenIds”是一个对象,但它是一个数组。此外,您正在复制点差。这导致返回的状态不再具有名为“chosenIds”的字段。
第三,如果没有找到 Array.indexOf() 则返回 -1,这实际上算作“真实”,因为它不是 0。因此,当前的 if/else 不会按您的预期执行。
我会将你的 reducer 改写成如下所示:
export default function reducer(state = initialState, action)
switch(action.type)
case ADD_TYPE:
let idAlreadyExists = state.chosenIds.indexOf(action.chosenId) > -1;
// make a copy of the existing array
let chosenIds = state.chosenIds.slice();
if(idAlreadyExists)
chosenIds = chosenIds.filter(id => id != action.chosenId);
else
// modify the COPY, not the original
chosenIds.push(action.chosenId);
return
// "spread" the original state object
...state,
// but replace the "chosenIds" field
chosenIds
;
default:
return state;
【讨论】:
啊当然……我完全忘记了。我不明白为什么你不能直接更新状态?可能只是一个 redux 规则角色 因为对象和数组在 javascript 中是通过引用传递的。当你改变你的状态时,你改变了先前的状态并使先前的状态与新的状态相同。因此 react-redux 不能再检测到新旧之间的变化,所以它不会更新。 除此之外,Redux 至少有两个地方进行浅层相等检查:在 reduce 调用结束时查看状态树的顶部,以及在 React-Redux 中比较返回值用于 mapStateToProps 以查看它们是否已更改。在这两个地方,如果旧值与新值的内容没有改变,它假定没有更深层次的改变,并且它实际上不需要做任何更多的事情(即通知订阅者或重新渲染包装的组件)。 【参考方案2】:另一种具有独立功能的方法:
export default function reducer(state = initialState, action)
switch(action.type)
case ADD_TYPE:
function upsert(array, item)
// (1)
// make a copy of the existing array
let comments = array.slice();
const i = comments.findIndex(_item => _item._id === item._id);
if (i > -1)
comments[i] = item;
return comments;
// (2)
else
// make a copy of the existing array
let comments = array.slice();
comments.push(item);
return comments;
return
...state,
comments: upsert(state.comments, action.payload),
;
default:
return state;
【讨论】:
以上是关于Redux reducer,检查状态数组中是不是存在值并更新状态的主要内容,如果未能解决你的问题,请参考以下文章
Redux 在存储中返回一个空数组 - Reducer 无法正常工作?
React Redux:reducers 是不是应该包含任何逻辑
如何在 React native redux 的 reducer 中向数组添加元素?