javascript - 如何在 useReduce 挂钩中发出异步服务器请求?
问题描述
我已经使用 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 })
}
我可以控制台记录返回的身份验证密钥,但我无法让我的减速器更新到返回的状态。
解决方案
在 a 中执行异步操作useReducer
是不可能的。如果我没记错的话,你的状态变成了一个承诺。
您必须做的是在外部执行该操作并通过调度传递数据。所以,你的 reducer 只处理数据。
此外,通过在外部抽象您的逻辑,您可能会对单元测试感兴趣,因此可以模拟不同场景的响应。如果它不适用,也许你想保持你的 API 隔离,不知道,每个应用程序/团队/开发人员都有自己的用例。
最后一点,如果你使用async/await
不要使用then
. 它是一个或另一个。
推荐阅读
- azure-logic-apps - 逻辑应用程序 - 从 Web 服务读取 xml 消息并存储在数据库中
- debugging - 嵌入式 Linux 内核调试
- android - 为什么我在创建表时遇到 sqlit 错误?
- python - 如何在不打开新页面的情况下访问页面的“检查元素”代码
- d3.js - D3以编程方式将html元素附加为子元素
- reactivesearch - ReactiveList 相关搜索
- javascript - 如何在 JavaScript 中应用快速求幂
- android - 为什么要在Activity中添加“向上按钮”时修改Java代码?
- java - 使用equals方法时Android Studio无法处理String中的问号?
- scala - Google 地图绘图在 ScalaFx WebView 中损坏