如何为 useReducer 键入 state 和 dispatch - typescript 和 react

Posted

技术标签:

【中文标题】如何为 useReducer 键入 state 和 dispatch - typescript 和 react【英文标题】:how to type state and dispatch for useReducer - typescript and react 【发布时间】:2020-04-13 08:58:06 【问题描述】:

我目前在当前设置中看到此错误。

输入 '( team: string | null; | team: string | null; | ...; | ...; | ...; | Dispatch<...>)[]' 缺少“状态”类型的以下属性:teamts(2739) index.d.ts(290, 9):预期类型来自属性“值”,该属性在此处在类型“IntrinsicAttributes & ProviderProps”上声明

我的代码如下,如果需要更多详细信息,请告诉我。

actions.ts

export const setTeam = (team: string | null) => (
  type: 'SET_TEAM',
  team,
);

reducer.ts

export const initialState = 
  team: null,
;

type State = 
  team: string | null;
;

export const GlobalContext = React.createContext<State | null>(null);

export const reducer = (state: State, action: any) => 
  switch (action.type) 
    case actionTypes.SET_TEAM:
      const team = action.team;
      return 
        ...state,
        team,
      ;

    default:
      return state;
  
;

App.tsx

const App = () => 
  const [state, dispatch] = React.useReducer(reducer, initialState);

  return ( 
    // error with state and dispatch here
    <GlobalContext.Provider value=[state, dispatch]>
        ...App code
    </GlobalContext.Provider>
  )

Team.tsx

import  GlobalContext  from './reducers';
import  setTeam  from './actions';

const Team = () => 
   const [, dispatch] = React.useContext(GlobalContext);

   return <span onClick=() => dispatch(setTeam('LFC'))>LFC</span>

【问题讨论】:

我不知道在哪里使用 setTeam() 或者为什么这在这种情况下很重要...... 您正在将上下文作为具有team 属性的对象键入,但您正在传递具有状态的数组并作为元素调度 @PatrickRoberts 更新了问题 @AsafAviv 那么你能解释一下我应该如何输入这个吗?抱歉,我不确定 【参考方案1】:

如果你想通过上下文传递状态和调度,你必须在上下文中键入它,你可以只使用这一行,但如果你想要类型安全,请进一步阅读

const GlobalContext = React.createContext<[State, React.Dispatch<any>]>([
   team: null ,
  () => ,
])

如果您希望操作的类型安全,您可以将 React.Dispatch 内的 &lt;any&gt; 更改为您的操作类型,您还需要在减速器内输入操作

enum TeamTypes 
  SET_TEAM = 'SET_TEAM',
  REMOVE_TEAM = 'REMOVE_TEAM',


type State = 
  team: string | null


export const initialState: State = 
  team: null,


type SetTeamAction = 
  type: typeof TeamTypes.SET_TEAM
  team: string


type RemoveTeamAction = 
  type: typeof TeamTypes.REMOVE_TEAM


type TeamActionTypes = SetTeamAction | RemoveTeamAction

export const setTeam = (team: string): TeamActionTypes => (
  type: TeamTypes.SET_TEAM,
  team,
)

export const GlobalContext = React.createContext<
  [State, React.Dispatch<TeamActionTypes>]
>([ team: null , () => ])

export const reducer = (state: State, action: TeamActionTypes): State => 
  switch (action.type) 
    case TeamTypes.SET_TEAM:
      const  team  = action
      return 
        ...state,
        team,
      
    default:
      return state
  


const App = () => 
  const [state, dispatch] = React.useReducer(reducer, initialState)

  return (
    <GlobalContext.Provider value=[state, dispatch]></GlobalContext.Provider>
  )

【讨论】:

感谢,但在添加 const GlobalContext = React.createContext&lt;[State, React.Dispatch&lt;any&gt;] | null&gt;(null) 后出现错误 This expression is not callable. Not all constituents of type 'State | Dispatch&lt;any&gt;' are callable. @peterflanagan 在您的动作创建者中键入type,并使用enum export const setTeam = (team: string | null) =&gt; ( type: TeamTypes.SET_TEAM, team, ); 上的类型 @peterflanagan 你可以制作一个沙箱或用你当前的代码更新问题,并从你得到错误的那行开始吗? 错误来自() =&gt; dispatch(setTeam('LFC')) @peterflanagan 检查this 与您的代码并告诉我有什么问题

以上是关于如何为 useReducer 键入 state 和 dispatch - typescript 和 react的主要内容,如果未能解决你的问题,请参考以下文章

useReducer 和 useState

useState & useReducer

TypeScript:如何为函数中的任何键键入对象剩余分布

Hook useReducer发送2次

React中useReducer的理解与使用

React中useReducer的理解与使用