reactjs - 如何在 createContext 中为 TypeScript 初始化 useState 的 set 函数?

标签 reactjs typescript react-hooks use-state

我有一个 Provider它通过两个 contexts 提供了一个状态变量及其对应的 setter .

const BookedBatchContext = createContext({})
const SetBookedBatchContext = createContext(null)

const initialState = {
  id: null
}
Provider看起来像这样:
export const BookedBatchProvider = ({ children }: { children: any }) => {
  const [bookedBatch, setBookedBatch] = useState(localState ||initialState)

  return (
    <SetBookedBatchContext.Provider value={setBookedBatch}>
      <BookedBatchContext.Provider value={bookedBatch}>
        { children }
      </BookedBatchContext.Provider>
    </SetBookedBatchContext.Provider>
  )
}

通过自定义 Hook ,我制作了 setBookedBatch可用于其他组件:
export const useBookedBatch = () => {
  const bookedBatch = useContext(BookedBatchContext)
  const setBookedBatch = useContext(SetBookedBatchContext)

  return { bookedBatch, setBookedBatch }
}

尝试使用 setBookedBatch 时函数,我在给定组件中出现以下错误:
setBookedBatch(selectedBatch)

错误:
TS2721: Cannot invoke an object which is possibly 'null'.

useState 的二传手function 是我没有创建的函数,我不知道在创建上下文时如何初始化它:
const SetBookedBatchContext = createContext(null)

这样 TypeScript 就不会提示了。
  • 如何知道 setter 函数的初始值?
  • 如果我没有提供任何类型,如何避免 TS 提示空值?
  • 最佳答案

    React.createContext的返回类型和 React.useState由您传入的初始值的推断确定。

    1.) 您可以通过手动指定泛型类型来创建正确的上下文类型:

    const SetBookedBatchContext = createContext<null | React.Dispatch<React.SetStateAction<State>>>(null)
    

    注意:useState 的 setter有类型 React.Dispatch<React.SetStateAction<State>> ,其中 State随便 localState || initialState是。

    2.) 在您的自定义 Hook 中断言 useBookedBatch ,那 setBookedBatch不是 null :
    export const useBookedBatch = () => {
      const bookedBatch = useContext(BookedBatchContext)
      const setBookedBatch = useContext(SetBookedBatchContext)
      if (setBookedBatch === null) throw new Error() // this will make setBookedBatch non-null
      return { bookedBatch, setBookedBatch }
      // returns: { bookedBatch: {}; setBookedBatch: React.Dispatch<React.SetStateAction<State>>; }
    }
    

    3.) 然后 setBookedBatch稍后可以在没有断言的情况下调用:
    const App = () => {
      const { setBookedBatch } = useBookedBatch()
      useEffect(() => { setBookedBatch({ id: "foo" }) }, [])
    }
    

    Sample on the playground

    关于reactjs - 如何在 createContext 中为 TypeScript 初始化 useState 的 set 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60712598/

    相关文章:

    angular - 如何按选定的值过滤数据?

    javascript - 如何使用react-testing-library测试material ui MenuList组件上的按键事件

    reactjs - TypeError - undefined 不是一个对象(评估 'c.currentObservable.query.refetch' )。在 native react 中

    javascript - TypeScript 找不到样式模块

    javascript - 钩子(Hook)没有在handleSubmit中被调用

    javascript - React Hook 实现导致并排计数变慢

    reactjs - 使用不同版本的 React 合并两个 React 应用程序

    javascript - 生成日期并将新属性添加到对象数组中

    node.js - 数据响应无法在 react 路由器中映射

    javascript - React 组件 this.variable 不渲染