我在学习还原工具包
我想要达到的目标:启动应用程序时,运行check()函数,通过getCredentials检索保存的凭据,如果存在(!= null),则使用这些凭据登录,如果不显示登录屏幕(当isAuthenticated === false时,登录屏幕可见)
出现以下错误:
Require cycle: state\reducers\authSlice.ts -> state\store.ts -> state\reducers\authSlice.ts
Require cycles are allowed, but can result in uninitialized values. Consider refactoring to remove the need for a cycle.
ERROR TypeError: undefined is not an object (evaluating '_authSlice.default.reducer')
如果我注解掉store.dispatch,那么代码运行时不会出错。
下面是代码:
store.tsx
import { configureStore } from "@reduxjs/toolkit";
import authSlice from "./reducers/authSlice";
export const store = configureStore({
reducer: {
auth: authSlice.reducer
}
});
export async function getStore(){
return store;
}
setImmediate(()=>{
store.dispatch(authSlice.actions.check());
})
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
authSlice.tsx
import { createSlice } from '@reduxjs/toolkit';
import type { PayloadAction } from '@reduxjs/toolkit'
import { store } from '../store';
import { isAuthenticated, login } from '../../api/auth';
import { getCredentials, saveCredentials } from '../../storage/auth';
import { Credentials } from '../../interfaces/auth';
interface AuthState {
isAuthenticated?: boolean
username?: string
}
const initialState: AuthState = {
isAuthenticated: undefined,
username: undefined
}
const authSlice = createSlice({
name: "auth",
initialState,
reducers: {
check(state){
if (state.isAuthenticated == undefined){
getCredentials().then(auth=>{
if (auth){
login(auth).then(()=>{
store.dispatch(authSlice.actions.loginSuccess(auth))
})
} else {
store.dispatch(authSlice.actions.unauthenticated())
}
})
}
},
loginSuccess(state,action: PayloadAction<Credentials>){
state.username = action.payload.username;
state.isAuthenticated = true;
},
unauthenticated(state){
state.isAuthenticated = false;
},
},
});
export default authSlice;
有些人说从reducer调用store.dispatch是一个反模式,但是我应该如何实现同样的逻辑呢?
1条答案
按热度按时间2j4z5cfb1#
还原剂必须是纯净的,这意味着(除其他外)两件事:
getCredentials
或login
,通常根本没有异步逻辑)。你在这里遗漏了很多基础知识,所以我建议你也许可以遵循官方的Redux Essentials Tutorial,阅读一下你应该如何处理副作用之类的事情,这种逻辑在reducer中是没有位置的。