亦余心之所善兮,虽九死其犹未悔。这篇文章主要讲述终极版/反应。实现后,combineReducers无法获得app的状态相关的知识,希望能为你提供帮助。
将两个reducers
组合在一起(EditButton
和TodoApp
)后,我的应用程序每次都开始崩溃。在它之前,当我只使用一个减速机TodoApp
时,我对reducers
没有任何问题。但现在我无法弄清楚出了什么问题,因为每次我在map
函数中得到component
的错误。错误“TypeError:无法读取未定义的属性'map'”。
那么,我忘记了什么?另外,我无法在App
的嵌套组件或容器中获取状态。这也很奇怪,但在App
中我可以通过console.log()来做到这一点。
/ * REDUCERS * /
import { combineReducers } from 'redux'
import { ADD_TODO, EDIT_TODO, DELETE_TODO, FILTER_TODO_UP, FILTER_TODO_DOWN } from '../Variables/Variables'const initialState = {
todos: []
}function EditButton(state, action) {
if (typeof state === 'undefined') {
return 'Edit';
}switch (action.type) {
case EDIT_TODO:
return state = "Edit" ? "Done" : "Edit"
default:
return state
}
}function TodoApp(state, action) {
if (typeof state === 'undefined') {
return initialState;
}switch (action.type) {
case ADD_TODO:
return Object.assign({}, state, {
todos: [
...state.todos,
{
id: action.id,
text: action.text,
done: action.done
}
]
});
case EDIT_TODO:
return Object.assign({}, state, {
todos: [
...state.todos,
{
id: action.id,
text: action.text,
done: action.done
}
]
});
case DELETE_TODO:
return Object.assign({}, {
todos: state.todos.filter(todos =>
todos.id !== parseInt(action.id))
});
case FILTER_TODO_UP:
return Object.assign({}, {
todos: [
...state.todos.sort((a, b) =>
b.id - a.id)
]
});
case FILTER_TODO_DOWN:
return Object.assign({}, {
todos: [
...state.todos.sort((a, b) =>
a.id - b.id)
]
});
default:
return state;
}
}export default combineReducers({TodoApp, EditButton})
【终极版/反应。实现后,combineReducers无法获得app的状态】/ * APP * /
import React, { Fragment } from 'react';
import TodoFormAdd from '../Containers/TodoFormAdd';
import TodoListAdd from '../Containers/TodoListAdd';
import TodoFormFilterAdd from '../Containers/TodoFormFilterAdd';
class App extends React.Component {
constructor(props) {
super(props);
}render() {
return(
<
Fragment>
// console.log(this.props.state.getState()) - work!
<
TodoFormAdd />
<
TodoListAdd store={this.props.store} />
<
TodoFormFilterAdd />
<
/Fragment>
);
}
}export default App;
/* 容器 */
import { connect } from 'react-redux';
import TodoList from '../Components/TodoList/TodoList';
import { DeleteTodo } from '../Actions/AddTodo'// console.log(this.props.state.getState()) - does not work!const mapStateToProps = state =>
({
todos: state.todos
});
const mapDispatchToProps = dispatch =>
({
todoFormDelete: todo =>
dispatch(DeleteTodo(todo))
});
export default connect(
mapStateToProps,
mapDispatchToProps)(TodoList)
/* 零件 */
import React from 'react';
import TodoIteam from '../TodoIteam/TodoIteam'class TodoList extends React.Component {
handleDelete = (e) =>
{
let target = e.target;
let closestDelete = target.closest('span');
let closestEdit = target.closest('button');
if (closestDelete) {
let index = closestDelete.parentNode.getAttribute('index');
this.props.todoFormDelete(index);
} else {
return
}
}render(props) {
// console.log(this.props.state.getState()) - does not work!return (
<
ul onClick={this.handleDelete}>
{this.props.todos.map((iteam, index) =>
// this where I get an error
<
TodoIteam key={index} index={iteam.id} {...iteam} />
)}
<
/ul>
);
}
}export default TodoList;
答案正如您在
combineReducers
中使用ES6属性简写表示法:combineReducers({TodoApp, EditButton})
这相当于写
combineReducers({ TodoApp: TodoApp, EditButton: EditButton })
但在你的CONTAINER里面你正在访问
state.todos
没有任何名为todos
来自州而不是它的TodoApp
因此你得到你的.map()
错误:this.props.todos.map((iteam, index) {}
编辑:当你从reducers中返回一个包含一个名为
todos
的数组的对象时,为了访问正确的状态你需要使用reducer Name后跟一个你要返回的数组名,这将是TodoApp.todos
因此,在您的Container内,您需要访问正确的
reducer
const mapStateToProps = state =>
({
todos: state.TodoApp.todos // Notice TodoApp is used instead of todos
});
你可以在Redux Documentation上阅读更多关于combineReducers的内容
推荐阅读
- 在Symfony 3中的表单上实现Google reCAPTCHA
- Android / Java,如何在某些字段中使用换行和逗号来处理csv文件()
- Google BigQuery APPROX_QUANTILES并获得真正的四分位数
- Swift didReceiveRemoteNotification - 无论app用户位于何处,都可以导航到rootviewcontroller(现在有错误信息)
- 如果用户在由本机生成的应用程序上隐藏了较低的硬件导航栏,则Android屏幕不适合
- Android Studio错误的含义(未注释的参数会覆盖@NonNull参数)
- ApplicationDataCompositeValue的大小
- AppFabric安装失败MSI错误代码(1603 |文件已存在)
- 由于Windows 8中的视频卡错误,无法启动Android Emulator和Genymotion。