如何在 useReducer 钩子中发出异步服务器请求?
Posted
技术标签:
【中文标题】如何在 useReducer 钩子中发出异步服务器请求?【英文标题】:How to make a asynchronous sever request in a useReduce hook? 【发布时间】:2021-07-26 21:23:04 【问题描述】:我已经使用 useContext 设置了一个 useReducer 挂钩来接收电子邮件和密码以用于登录目的,我已经创建了一个组件来从服务器获取身份验证令牌。我目前无法弄清楚如何使用返回的 accessToken 更新减速器。
减速器
export const loginInitialState =
isLogin: false,
accessToken: '',
as LoginInitialState
//this is the part that is not working
export const loginReducer = async (
state: LoginInitialState,
actionType, email, password : LoginPayload
) =>
switch (actionType)
case 'login':
const data = await loginRequest(email, password)
console.log(data)
return
...data,
case 'logout':
return
...loginInitialState,
使用上下文
export const LoginStateContext = createContext<LoginStateContextProps>(false)
export const LoginDispatchContext = createContext<LoginDispatchContextProps>(
() =>
)
export const AccessTokenContext = createContext<AccessTokenProps>('')
export const LoginProvider = (
children,
: React.PropsWithChildren<unknown>) =>
//@ts-ignore
const [isLogin, dispatchLogin] = useReducer(loginReducer, loginInitialState)
return (
<AccessTokenContext.Provider value=isLogin.accessToken>
<LoginDispatchContext.Provider value=dispatchLogin>
<LoginStateContext.Provider value=isLogin.isLogin>
children
</LoginStateContext.Provider>
</LoginDispatchContext.Provider>
</AccessTokenContext.Provider>
)
获取请求
export const loginRequest = async (email?: string, password?: string) =>
let data: any
await axios
.post(`blah blah blah`,
emailAddress: email,
password: password,
)
.then((res) =>
data = res.data
)
if (data)
return
isLogin: true,
accessToken: data.accessToken,
else
return ...loginInitialState
调度点
const onLoginClick = () =>
dispatchLogin( actionType: 'login', email: email, password: password )
我可以通过控制台记录返回的身份验证密钥,但我无法让 reducer 更新到返回的状态。
【问题讨论】:
我假设您的意思是标题中的“异步”而不是“同步”? 啊,是我的错,谢谢 【参考方案1】:不可能在useReducer
中执行异步操作。如果我没记错的话,你的状态就是一个承诺。
您必须做的是在外部执行该操作并通过调度传递数据。所以,你的 reducer 只处理数据。
此外,通过在外部抽象您的逻辑,您可能会对单元测试感兴趣,因此可以模拟不同场景的响应。如果它不适用,也许你想保持你的 API 隔离,不知道,每个应用程序/团队/开发人员都有自己的用例。
最后一点,如果您使用async/await
,请不要使用then
。要么是一个,要么是另一个。
【讨论】:
我已将其更改为 useState 挂钩,只需在所需目的地设置状态即可解决问题,但感谢您的回复!以上是关于如何在 useReducer 钩子中发出异步服务器请求?的主要内容,如果未能解决你的问题,请参考以下文章
React 用 useReducer 替换 useState,同时还使用自定义钩子