【发布时间】:2021-09-12 14:53:30
【问题描述】:
这里我想创建一个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>
)
}
这是我的减速器:
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,
}
}
}
这是我在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)
这是我在<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)
有谁知道解决方案或告诉发生了什么?谢谢
编辑:
当我在登录页面上使用我的上下文时,我遇到了另一个问题。
这是我的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>
)
}
当我运行代码时,显示如下错误:
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.
我已阅读文档,但我认为我没有违反任何钩子规则。我哪里做错了对不起我是新手。
【问题讨论】:
-
你的上下文的初始值只是状态,但它需要是一个同时具有状态和调度的对象。
-
我似乎误解了我应该在上下文中输入的内容,非常感谢您的帮助,它真的帮助了我
标签: reactjs typescript use-context use-reducer