reactjs - 从存储中存储和检索状态
问题描述
我正在尝试userToken
在 Redux 存储中保存并检索它。在我的index.js
我包装我App
的 with Provider
,它store
作为道具:
import { createStore } from "redux";
import { Provider } from "react-redux";
import rootReducer from "./reducers/rootReducer";
const store = createStore(rootReducer);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
我的rootReducer
样子是这样的:
//Helper functions
import { validateLoginAttempt } from "../helpers/validateLoginAttempt";
const rootReducer = (state, action) => {
switch (action.type) {
case "login":
const isLoggedIn = validateLoginAttempt(action.payload);
default:
console.log("default");
break;
}
};
export default rootReducer;
我定义了一个辅助函数validateLoginAttempt
:
export const validateLoginAttempt = payload => {
if (typeof payload.data.token !== "undefined") {
//Saves in localstorage correctly.
localStorage.setItem("userToken", payload.data.token);
return true;
}
return false;
};
在我的一个功能组件中,我有一个fetch()
程序,在对 API 的请求结束时,它是dispatch()
我在我的定义中定义的操作rootReducer
:
const dispatch = useDispatch();
<...>
.then(data => {
dispatch({ type: "login", payload: { data } });
history.push("/");
})
useCase
至少从我的理解来看,这个流程按预期工作,值被存储在localStorage
其中(我假设它不是 Redux store
?)。在我的另一个组件中,我试图userToken
像这样检索:
const userToken = useSelector(state => state.userToken);
这给了我一个error
:
Error: An error occured while selecting the store state: Cannot read property 'userToken' of undefined.
如果我在我的组件中尝试getStore
如下操作,我会得到:App
store undefined
const store = useStore();
console.log("store", store.getState());
有人可以让我走上正轨,无法弄清楚。
解决方案
有多个问题,但最大的一个与减速器的基础有关:
reducer 是一个纯函数,它接受前一个状态和一个动作,并返回下一个状态。
您不会从减速器(隐式return undefined
)返回任何内容,从而导致 TypeError Cannot read property 'userToken' of undefined.
:
const initialState = {};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case "login": {
return {...state, userToken: action.payload.data.token};
}
default:
return state;
}
};
而“纯函数”意味着没有副作用,所以localStorage.setItem
内部validateLoginAttempt
在 reducer 中没有位置,应该放在 action creator 内部:
const dispatch = useDispatch();
...
.then(data => {
const isLoggedIn = validateLoginAttempt(data);
if (isLoggedIn) {
dispatch({ type: "login", payload: { data } });
history.push("/");
} else {
console.error("not logged in")
}
})
推荐阅读
- mfc - 如果分辨率太小,调整大小的对话框不会显示滚动条
- javascript - Matter.js 设置世界的界限(边缘)
- gnu-make - 为什么在 gnu make 4 的定义指令中添加了可选的 '='?
- xml - 如何配置架构以接受带有不带前缀的命名空间的 xml 文档
- hadoop - 我无法从 Hadoop 客户端访问 Hadoop 服务器
- arrays - 如何使用 reduce(into:_:) 将数组转换为二维数组?
- mysql - 每个俱乐部会员资格的 WooCommerce 购买摘要 (mySQL)
- javascript - 未找到 React 模块 - 无法解决问题
- python - 如何防止并发期货库循环先前迭代的项目?
- php - 在 PHP 中的服务器之间传递变量值