Reactjs 使用useReducer和带有Typescript的上下文时出现类型错误

Reactjs 使用useReducer和带有Typescript的上下文时出现类型错误,reactjs,typescript,next.js,Reactjs,Typescript,Next.js,我正在尝试在React应用程序中包含带有useReducer和上下文的Auth,但在中有一个类型错误 错误是: Type 'Dispatch<Action>' is not assignable to type '(state: User, action: Action) => { id: number | null; username: string | null; email: string | null; role: 'user' | 'admin'; }'. Typ

我正在尝试在React应用程序中包含带有useReducer和上下文的Auth,但在中有一个类型错误

错误是:

Type 'Dispatch<Action>' is not assignable to type '(state: User, action: Action) =>
{ id: number | null; username: string | null; email: string | null; role: 'user' | 'admin'; }'.
  Types of parameters 'value' and 'state' are incompatible.
    Property 'type' is missing in type 'User' but required in type 'Action'.
这是Auth.tsx

import React, { useReducer, useContext } from 'react'
import { NextPage } from 'next'
import { User, Action } from '../@types/auth'

const user: User = {
    id: null,
    username: null,
    email: null,
    role: null
}

const reducer = (state: User, action: Action) => {
    switch (action.type) {
        case 'login':
            return {...state}
        default:
          return {...state, ...user}
    }
}

const UserStateContext = React.createContext<User>(user)
const UserDispatchContext = React.createContext<typeof reducer>(reducer)

export const AuthProvider: NextPage = ({ children }) => {

    const [ state, dispatch ] = useReducer(reducer, user)

    return (
        <UserStateContext.Provider value={state}>
            <UserDispatchContext.Provider value={dispatch}>
                {children}
            </UserDispatchContext.Provider>
        </UserStateContext.Provider>
    )
}

export const useAuth = () => useContext(UserStateContext)
export const useDispatchAuth = () => useContext(UserDispatchContext)
我试过一些东西,但我想不出来。 也许我还不太了解useReducer是如何工作的


提前感谢

我很难通过查看来调试这段代码,但我将向您展示非常类似的代码,希望您能从中获得一些东西。主要是我使用了类型安全操作:

index.tsx:

import React, { createContext, useContext, useEffect, useReducer } from 'react';
import { ActionType } from 'typesafe-actions';

import * as actions from './app.actions';
import * as userActions from './user/actions';

import * as fromUser from './user/reducer';


interface State {
  user: fromUser.State,
}

const appReducer = (state: State, action: ActionType<typeof actions>) => ({
  user: fromUser.reducer(state.user, action as ActionType<typeof userActions>),
});

const initialState: State = {
  user: fromUser.initialState,
};


const StateContext = createContext(initialState);
const DispatchContext = createContext((_: ActionType<typeof actions>) => { });

interface ProviderProps { children: React.ReactNode }

export const StoreProvider: React.FC<ProviderProps> = ({ children }) => {
  const [state, dispatch] = useReducer(appReducer, initialState);

  useEffect(() => {
    dispatch(actions.appStart());
    return () => dispatch(actions.appEnd());
  }, []);

  return (
    <StateContext.Provider value={state}>
      <DispatchContext.Provider value={dispatch}>
        {children}
      </DispatchContext.Provider>
    </StateContext.Provider>
  );
};

export function useStore() {
  return useContext(StateContext);
}

export function useDispatch() {
  return useContext(DispatchContext);
}
/用户/减速器:

import { ActionType } from 'typesafe-actions';

import * as actions from './actions';


export interface State {
  userName: string | null,
}

export const initialState: State = {
  userName: null,
};

export const reducer = (state = initialState, action: ActionType<typeof actions>): State => {
  switch (action.type) {
    case actions.ADD_USER: {
      return {
        userName: action.user,
      };
    }
    case actions.REMOVE_USER: {
      return {
        userName: null,
      };
    }
    default: return state;
  }
};

我很难通过查看来调试这段代码,但我将向您展示非常类似的代码,希望您能从中获得一些东西。主要是我使用了类型安全操作:

index.tsx:

import React, { createContext, useContext, useEffect, useReducer } from 'react';
import { ActionType } from 'typesafe-actions';

import * as actions from './app.actions';
import * as userActions from './user/actions';

import * as fromUser from './user/reducer';


interface State {
  user: fromUser.State,
}

const appReducer = (state: State, action: ActionType<typeof actions>) => ({
  user: fromUser.reducer(state.user, action as ActionType<typeof userActions>),
});

const initialState: State = {
  user: fromUser.initialState,
};


const StateContext = createContext(initialState);
const DispatchContext = createContext((_: ActionType<typeof actions>) => { });

interface ProviderProps { children: React.ReactNode }

export const StoreProvider: React.FC<ProviderProps> = ({ children }) => {
  const [state, dispatch] = useReducer(appReducer, initialState);

  useEffect(() => {
    dispatch(actions.appStart());
    return () => dispatch(actions.appEnd());
  }, []);

  return (
    <StateContext.Provider value={state}>
      <DispatchContext.Provider value={dispatch}>
        {children}
      </DispatchContext.Provider>
    </StateContext.Provider>
  );
};

export function useStore() {
  return useContext(StateContext);
}

export function useDispatch() {
  return useContext(DispatchContext);
}
/用户/减速器:

import { ActionType } from 'typesafe-actions';

import * as actions from './actions';


export interface State {
  userName: string | null,
}

export const initialState: State = {
  userName: null,
};

export const reducer = (state = initialState, action: ActionType<typeof actions>): State => {
  switch (action.type) {
    case actions.ADD_USER: {
      return {
        userName: action.user,
      };
    }
    case actions.REMOVE_USER: {
      return {
        userName: null,
      };
    }
    default: return state;
  }
};