frs*_*nmk 0 typescript reactjs use-reducer use-context
这里我想创建一个AuthContext来将用户状态共享给其他组件。这里我使用 TypeScript 来设置变量类型。但是当我试图解决这个问题时,我遇到了很多错误。我对这个问题非常困惑。
这是我的AuthContext:
import { createContext, ReactNode, useReducer } from 'react'
import { AuthReducer } from './Reducer';
export interface IState {
isAuthenticated: boolean
user: string | null
token: string | null
}
// interface for action reducer
export interface IAction {
type: 'LOGIN' | 'LOGOUT' | 'REGISTER' | 'FORGOT PASSWORD'
payload?: any
}
interface IAuthProvider {
children: ReactNode
}
const initialState = {
isAuthenticated: false,
user: '',
token: ''
}
export const AuthContext = createContext<IState>(initialState);
export const AuthProvider = ({ children }: IAuthProvider) => {
const [state, dispatch] = useReducer(AuthReducer, initialState)
return (
<AuthContext.Provider value={{ state, dispatch }}>
{children}
</AuthContext.Provider>
)
}
Run Code Online (Sandbox Code Playgroud)
这是我的减速器:
import { IAction, IState } from ".";
export const AuthReducer = (state: IState, action: IAction) => {
switch (action.type) {
case 'LOGIN':
localStorage.setItem("user", action.payload.user)
localStorage.setItem("token", action.payload.token)
return {
...state,
isAuthenticated: true,
user: action.payload.user,
token: action.payload.token
}
case 'LOGOUT':
localStorage.clear()
return {
...state,
isAuthenticated: false,
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的错误useReducer:
No overload matches this call.
Overload 1 of 5, '(reducer: ReducerWithoutAction<any>, initializerArg: any, initializer?: undefined): [any, DispatchWithoutAction]', gave the following error.
Argument of type '(state: IState, action: IAction) => { isAuthenticated: boolean; user: any; token: any; } | undefined' is not assignable to parameter of type 'ReducerWithoutAction<any>'.
Overload 2 of 5, '(reducer: (state: IState, action: IAction) => { isAuthenticated: boolean; user: any; token: any; } | undefined, initialState: never, initializer?: undefined): [...]', gave the following error.
Argument of type '{ isAuthenticated: boolean; user: string; token: string; }' is not assignable to parameter of type 'never'.ts(2769)
Run Code Online (Sandbox Code Playgroud)
这是我的错误<AuthContext.Provider value={{ state, dispatch }}>:
Type '{ state: any; dispatch: React.DispatchWithoutAction; }' is not assignable to type 'IState'.
Object literal may only specify known properties, and 'state' does not exist in type 'IState'.ts(2322)
Run Code Online (Sandbox Code Playgroud)
有谁知道解决方案或告诉发生了什么?谢谢
编辑:当我在登录页面上使用上下文时,我遇到了另一个问题。这是我的LoginPage:
import React, { FC, useContext } from 'react'
import { AuthContext } from '../AuthContext'
export const Login: FC<IProps> = () => {
const { state, dispatch } = useContext(AuthContext)
const login = () => {
dispatch({
type: 'LOGIN',
payload: { ...state, isAuthenticated: !state.isAuthenticated }
})
}
return (
<div>
<input name="username" />
<button onClick={login}></button>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
当我运行代码时,它显示如下错误:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
Run Code Online (Sandbox Code Playgroud)
我已阅读文档,但我认为我没有违反任何挂钩规则。我哪里错了抱歉我是新来的反应。
您正在创建的上下文和您正在使用的上下文之间不匹配。
您创建一个上下文,其value是类型为的状态对象IState:
export const AuthContext = createContext<IState>(initialState);
Run Code Online (Sandbox Code Playgroud)
您使用的上下文value是一个具有属性state和 的对象dispatch:
<AuthContext.Provider value={{ state, dispatch }}>
Run Code Online (Sandbox Code Playgroud)
为了修复这种不匹配,您必须AuthContext以符合您想要使用它的方式来定义您的。 上下文值需要是一个具有属性的对象state,并且dispatch。
这里我们为上下文值定义一个接口。的默认值state是记录错误消息initialState的默认值。dispatch
interface AuthContextValue {
state: IState;
dispatch: React.Dispatch<IAction>;
}
export const AuthContext = createContext<AuthContextValue>({
state: initialState,
dispatch: (action) => console.error("Dispatched action outside of an AuthContext provider", action)
});
Run Code Online (Sandbox Code Playgroud)
这是一个更简单的版本,我们内联定义上下文值类型,并且在dispatch使用默认值调用时不执行任何操作。
export const AuthContext = createContext<{state: IState; dispatch: React.Dispatch<IAction>}>({
state: initialState,
dispatch: () => {},
});
Run Code Online (Sandbox Code Playgroud)
我在您的减速器上收到一个不相关的错误,TS 7030“并非所有代码路径都返回值。” 减速器应该始终有一个defaultcaseswitch以避免返回undefined状态。
default: return state;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1513 次 |
| 最近记录: |