如何从减速器删除条目/如何返回一个新的状态?(React / Redux)
How to deleting Entries from Reducer / how to return a new state? (React / Redux)
我的reducer默认返回如下(它来自教程):
return [
{
id: 1,
first: "Bucky",
last: "Roberts",
age: 71,
description: "Bucky is a React developer and YouTuber",
thumbnail: "http://i.imgur.com/7yUvePI.jpg"
},
{
id: 2,
first: "Joby",
last: "Wasilenko",
age: 27,
description: "Joby loves the Packers, cheese, and turtles.",
thumbnail: "http://i.imgur.com/52xRlm8.png"
},
{
id: 3,
first: "Madison",
last: "Williams",
age: 24,
description: "Madi likes her dog but it is really annoying.",
thumbnail: "http://i.imgur.com/4EMtxHB.png"
}
]
}
我现在希望能够从这个"列表"中删除用户条目。所以我继续构建一个删除用户操作创建器等,所以除了上面的数据之外,现在在它前面有以下代码:
switch (action.type) {
case 'USER_DELETED':
console.log("Hello from reducer-users");
let newState = Object.assign({}, state, );
// console.log(newState == state);
// console.log(newState.users == state.users)
// delete newState.users;
return newState;
break;
}
的想法是,如果有人点击'DELETE USER',这个函数被调用,并返回一个新的状态,适当的用户被删除。它还可以在调用函数的情况下工作(显示console.log)。然而,我不知道如何去删除用户从这个列表现在?我明白我需要复制当前状态,然后从副本中删除用户,&然后返回副本,使其成为新状态。这是正确的吗?如果是这样,我不知道该怎么做。如果我尝试执行上面写的东西,这只是s.b.在stackoverflow上写的东西,我会得到一个错误:
user-list.js吗?未捕获的类型错误:this.props.users.map不是一个函数(…)renderList @ user-list.js?1 cc2:11render @?d41d:33(匿名函数)@ReactCompositeComponent.js吗?cd59:793measureLifeCyclePerf @ReactCompositeComponent.js吗?cd59:74_renderValidatedComponentWithoutOwnerOrContext@ ReactCompositeComponent.js吗?cd59:792_renderValidatedComponent @ReactCompositeComponent.js吗?cd59:819_updateRenderedComponent @ReactCompositeComponent.js吗?cd59:743_performComponentUpdate @ReactCompositeComponent.js吗?cd59:721updateComponent @ReactCompositeComponent.js吗?cd59:642receiveComponent @ReactCompositeComponent.js吗?cd59:544receiveComponent @ReactReconciler.js吗?6论坛:126 _updaterenderedcomponent @ReactCompositeComponent.js吗?cd59:751_performComponentUpdate @ReactCompositeComponent.js吗?cd59:721updateComponent @ReactCompositeComponent.js吗?cd59:642performUpdateIfNecessary @ReactCompositeComponent.js吗?cd59:558performUpdateIfNecessary @ReactReconciler.js吗?6论坛:158 runbatchedupdates @ReactUpdates.js吗?[09:15 .js]6 dff: 138 @执行Transaction.js吗?6 dff: 138 @执行ReactUpdates.js吗?ce09:90flushBatchedUpdates @ReactUpdates.js吗?[09:17 . 03] close all @ Transaction.js?6 dff: 204 @执行Transaction.js吗?6 dff: 151 batchedupdates @ReactDefaultBatchingStrategy.js吗?ef70:63batchedUpdates @ReactUpdates.js吗?[09:98] dispatchevent @ ReactEventListener.js?2365:150
这是整个reducers文件:
/*
* The users reducer will always return an array of users no matter what
* You need to return something, so if there are no users then just return an empty array
* */
export default function (state = null, action) {
switch (action.type) {
case 'USER_DELETED':
console.log("Hello from reducer-users");
//let newState = Object.assign([{}], state);
// return newState;
return state.filter(user => user.id !== action.userIdToDelete);
console.log("UNTIL HERE");
// console.log(newState.users == state.users)
// delete newState.users;
// return ([{
// id: 5,
// first: "Bucky",
// last: "Roberts",
// age: 71,
// description: "Bucky is a React developer and YouTuber",
// thumbnail: "http://i.imgur.com/7yUvePI.jpg"
// }]);
break;
console.log("UNTIL HERE2222");
}
return [
{
id: 1,
first: "Bucky",
last: "Roberts",
age: 71,
description: "Bucky is a React developer and YouTuber",
thumbnail: "http://i.imgur.com/7yUvePI.jpg"
},
{
id: 2,
first: "Joby",
last: "Wasilenko",
age: 27,
description: "Joby loves the Packers, cheese, and turtles.",
thumbnail: "http://i.imgur.com/52xRlm8.png"
},
{
id: 3,
first: "Madison",
last: "Williams",
age: 24,
description: "Madi likes her dog but it is really annoying.",
thumbnail: "http://i.imgur.com/4EMtxHB.png"
}
]
}
您说的对,您的reducer应该返回状态的新副本,而不改变当前的状态。这种方法有几个非常好的好处(见这里:http://redux.js.org/docs/Glossary.html#reducer)
假设这个reducer管理的状态是一个数组,要从列表中删除一个用户,您可以执行以下操作:
switch (action.type) {
case 'USER_DELETED':
return state.filter(user => user.id !== action.userIdToDelete);
}
关键是数组。Filter返回一个新数组,对每个元素应用回调,决定保留/过滤哪个元素,它不会改变原始数组。查看这里的文档https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
您可能想使用Array。splice代替(https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/splice),但在这种情况下,这将是错误的,因为splice
"通过删除现有元素和/或添加新元素来改变数组的内容。",所以它确实改变了原来的一个。
注意你需要在你的动作有效载荷中传递userIdToDelete
。
同样,你不需要break
,因为你已经在使用return
了。
至于你发布的错误的确切原因,问题是,此刻你的减速机正在返回一个对象而不是一个数组:let newState = Object.assign({}, state, );
然后,在你的组件的某个地方,你正在从状态中读取,你正试图调用map
在你的状态,这不再是一个数组(因此没有map
方法定义为this.props.users
另一个建议:
我真的建议你开始在你的reducer中使用纯Js,总是小心那些在适当的地方改变对象的方法。在你知道你在做什么之后,有时在Js中使用不可变数据结构可能会很笨拙,所以你可以开始研究使用这些库来减轻更复杂场景的痛苦(但只有在你真的需要的时候),按复杂性排序(显然在我看来):
- https://facebook.github.io/react/docs/update.html
- https://github.com/substantial/updeep
- https://facebook.github.io/immutable-js/
- 使用react router/react router redux将特定的redux操作绑定到一个路由
- reactjs-redux,是否可以有一个由2个组件使用的状态
- React+Redux-期望reducer是一个函数
- 使用 Redux fetch 的 React js 总是返回一个空的 json
- 在 React/Redux 应用程序中,我应该何时显式传递一个 prop,而不是使用 mapStateToProps 从
- 我可以在React和Redux中发送一个AJAX调用,而不需要操作创建者和还原器吗
- 如何在redux模块中创建一个helper类型的函数,从state返回一组经过过滤的只读数据
- Dispatch()调用一个函数,但是.then()不调用;我不在React Redux上工作
- Redux 操作创建者在另一个内部调用一个
- redux/react 应用程序中的状态有一个带有化简器名称的属性
- 'dispatch' 在 Redux 中向 mapToDispatchToProps() 参数时不是一个函数
- ES6/Redux:返回一个函数来删除事件侦听器
- 反应 Redux 异步操作在完成函数后调用下一个函数
- Redux如何在ajax完成后打开一个新窗口
- React+Redux router=未捕获错误:要求reducer是一个函数
- Redux:每个记录一个表单,可能有数千条记录
- 如何减少react-redux样板——我尝试创建一个ComponentFactory,但是我得到了react-redux
- 我如何从我的API模块调度一个redux操作?
- 在Redux存储中保留一个id列表
- 用React和redux从不同的reducer调用一个动作