我正在尝试在Redux存储区中保存userToken
并进行检索。在我的index.js
中,我的App
用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());
有人能把我放在正确的轨道上,无法弄清楚这一点。
答案 0 :(得分:1)
存在多个问题,但最大的问题与basics of reducers有关:
reduceer是一个纯函数,它具有上一个状态和一个动作,并返回下一个状态。
您没有从化简器返回任何内容(隐式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中没有位置,应放置在动作创建者内部:
const dispatch = useDispatch();
...
.then(data => {
const isLoggedIn = validateLoginAttempt(data);
if (isLoggedIn) {
dispatch({ type: "login", payload: { data } });
history.push("/");
} else {
console.error("not logged in")
}
})