Redux:动作已成功调度,但未创建状态
Posted
技术标签:
【中文标题】Redux:动作已成功调度,但未创建状态【英文标题】:Redux: Action was successfully dispatched but the State was not created 【发布时间】:2021-04-16 01:01:46 【问题描述】:我只是在制作一个简单的应用程序来学习 Redux。我使用 Redux DevTools 查看我的 2 个状态:lists 和 todos。但是它只显示 todos,虽然我尝试了我所知道的一切,但它没有显示 lists:
初始状态:
点击“添加”按钮后:
这是我的代码:
lists.js
import createSlice from "@reduxjs/toolkit";
const slice = createSlice(
name: "lists",
initialState: [],
reducers:
listAdded: (lists, action) =>
lists.push(
id: action.payload.id,
title: action.payload.title,
todos: action.payload.todos,
);
,
,
);
export const listAdded = slice.actions;
export default slice.reducer;
todos.js
import createSlice from "@reduxjs/toolkit";
const slice = createSlice(
name: "todos",
initialState: [],
reducers:
todoAdded: (todos, action) =>
todos.push(
id: action.payload.id,
content: action.payload.content,
check: action.payload.check
);
,
todoEdited: (todos, action) =>
const index = todos.findIndex((todo) => todo.id === action.payload.id);
todos[index].content = action.payload.content;
);
export const todoAdded, todoEdited = slice.actions;
export default slice.reducer;
reducer.js
import combineReducers from "redux";
import todosReducer from "./todos";
import listsReducer from "./lists";
export default combineReducers(
lists: listsReducer,
todos: todosReducer
);
configureStore.js
import configureStore from "@reduxjs/toolkit";
import reducer from "./reducer";
const store = () =>
return configureStore( reducer );
;
export default store();
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import store from "./configureStore";
import Provider from "react-redux";
ReactDOM.render(
<React.StrictMode>
<Provider store=store>
<App />
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
如您所见,它在我使用 dispatch 之后执行操作。但是,因为它没有 state,所以当我使用 lists.map 时,它会显示 'TypeError: Cannot read property 'map' of undefined'
请问我做错了什么?请帮忙!我很感激!
编辑:放更多与添加按钮相关的代码:
App.js
import React from "react";
import ItemTodo from "./ItemTodo";
import ItemList from "./ItemList";
import useSelector from "react-redux";
import NewListButton from "./NewListButton";
import NewTodoButton from "./NewTodoButton";
function App()
const todos = useSelector((state) => state.todos);
const lists = useSelector((state) => state.lists);
return (
<div className="App">
<div className="todo-list">
<NewListButton />
<div>
lists.map((item) => (
<ItemList key=item.id title=item.title />
))
</div>
<div>
<h2>write a todo</h2>
todos.map((item) => (
<ItemTodo
key=item.id
id=item.id
content=item.content
check=item.check
/>
))
<NewTodoButton />
</div>
</div>
</div>
);
export default App;
ItemList.js
import React from "react";
const ItemList = ( title ) =>
return (
<div className="list-item">
<h2>title</h2>
<div className="list-edit">edit name</div>
<div className="list-remove">remove list</div>
</div>
);
;
export default ItemList;
ItemTodo.js
import React, useState from "react";
import useDispatch from "react-redux";
import todoEdited from "./todos";
const ItemTodo = ( id, content, check ) =>
const dispatch = useDispatch();
const [contentX, setContentX] = useState("");
const inputTodo = (e) =>
setContentX(e.target.value);
;
const clickEdit = (e) =>
e.preventDefault();
dispatch(todoEdited( id, content: contentX ));
;
return (
<div>
<form className="nav-submit">
<input
type="text"
onClick=inputTodo
onChange=inputTodo
value=contentX
onBlur=clickEdit
/>
</form>
</div>
);
;
export default ItemTodo;
NewListButton.js
import listAdded from "./lists";
import v4 as uuidv4 from "uuid";
import useDispatch from "react-redux";
import React, useState from "react";
const NewListButton = () =>
const dispatch = useDispatch();
const [titleX, setTitleX] = useState("");
const getListTitle = (e) =>
setTitleX(e.target.value);
;
const setNewList = (e) =>
e.preventDefault();
const id = uuidv4();
dispatch(listAdded( id, title: titleX, todos: [] ));
setTitleX("");
;
return (
<div className="nav-list">
<h2>write a list</h2>
<form action="">
<input type="text" onChange=getListTitle value=titleX />
<button className="button-newlist" onClick=setNewList>
New List
</button>
</form>
</div>
);
;
export default NewListButton;
NewTodoButton.js
import React from "react";
import v4 as uuidv4 from "uuid";
import useDispatch from "react-redux";
import todoAdded from "./todos";
const NewTodoButton = () =>
const id = uuidv4();
const dispatch = useDispatch();
const newTodo = (e) =>
e.preventDefault();
dispatch(todoAdded( id, content: "", check: true ));
;
return (
<div>
<button className="button-new" onClick=newTodo>
New Todo
</button>
</div>
);
;
export default NewTodoButton;
编辑:更多信息。
这里有点奇怪:
我添加了一个文件:ListInitialState.js
const ListInitialState = [
id: 1,
title: "first list",
todos: [],
,
];
export default ListInitialState;
然后将 ListInialState.js 导入 list.js:
import ListInitialState from "./ListInitialState";
import createSlice from "@reduxjs/toolkit";
const slice = createSlice(
name: "lists",
initialState: ListInitialState,
reducers:
listAdded: (lists, action) =>
lists.push(
id: action.payload.id,
title: action.payload.title,
todos: action.payload.todos,
);
,
,
);
export const listAdded = slice.actions;
export default slice.reducer;
终于成功了,但我不知道为什么:
如果有人解释它会很棒。我真的很感激!
【问题讨论】:
您的 listsReducer 是否有默认状态?你可以在问题中添加它吗? @Ashu 抱歉,这是什么意思?如何将其状态设置为默认值? 放一些添加按钮和触发reducer相关的代码? @Kalhan.Toress 抱歉,我认为这些代码足以获取状态。添加了更多代码。谢谢! 【参考方案1】:可能你没有启用 redux 开发工具。
您可以使用此配置启用 redux 开发工具。
const store = configureStore(
reducer,
devTools: process.env.NODE_ENV !== 'production',
)
Redux DevTools Extension 已禁用生产
【讨论】:
您好,谢谢!我在 configureStore.js 中尝试了您的代码,然后“导出默认存储;”但它和以前一样吗? 他的 todo reducer 的状态正在显示,所以可能与 devtools 未连接有关 @Ashu 是的,问题是动作已经成功调度,但状态从未创建。 正如我之前提到的,你错过了初始状态,因此它直到你分派了动作才显示出来,redux 在开始时运行每个减速器,这些减速器返回一个初始状态,该状态存储在店铺。但我看到在 createSlice 你确实传递了一个空数组以上是关于Redux:动作已成功调度,但未创建状态的主要内容,如果未能解决你的问题,请参考以下文章
在通过动作调度进行状态更新后,在 React 中使用 Redux 执行函数?