【问题标题】:Context Provider in TypeScriptTypeScript 中的上下文提供程序
【发布时间】:2021-01-25 17:18:43
【问题描述】:

我得到了最简单的 ES6 上下文提供程序,但我无法将其转换为用于 TypeScript 项目。我搜索的每个网站在实现上下文 api 方面都有完全不同的看法。

它只是一个布尔变量和一个设置它的函数,我一直遇到 TypeScript 的问题。

我是否需要更改整个方法以使其适用于 TypeScript?

context.js

import React from 'react'
import Reducer from './reducer'

export const LoadContext = React.createContext()

export const LoadProvider = ({ children }) => {
  const [state, dispatch] = React.useReducer(Reducer, {
    load: true
  })

  const setLoad = (load) => dispatch({ type: 'set_load', load })

  return (
    <LoadContext.Provider value={{ load: state.load, setLoad }}>
      {children}
    </LoadContext.Provider>
  )
}

export const useLoadContext = () => React.useContext(LoadContext)

reducer.js

export default (state, action) => {
  switch (action.type) {
    case 'set_load':
      return {
        load: action.load
      }
    default:
      return state
  }
}

【问题讨论】:

    标签: reactjs typescript react-context


    【解决方案1】:

    通常你会想要输入你的上下文,例如:

    type LoadContextType = {
      load: any // Not sure what these are, type it appropriately
      setLoad: any
    }
    
    const context LoadContext = React.CreateContext<LoadContextType>(null)
    

    因此,当使用LoadContext 的提供者或消费者时,类型是已知的。

    【讨论】:

    • 我已经为创建上下文添加了类型
    • 这个有问题,如果我不加&lt;LoadContextType | null&gt;(null) TypeScript会报错:Argument of type 'null' is not assignable to parameter of type 'LoadContextType'
    • 您可能在 tsconfig.json 中有 --strictNullChecks 作为编译器参数或 "strictNullChecks": true。作为参数提供的null 是您的上下文的默认/初始值。您可以删除编译器参数或提供非空对象作为默认参数。
    • 是的,正确,在tsconfig.json 我得到了"strictNullChecks": true,。它的工作原理是将| 添加到类型定义中,然后将 null 作为默认值
    【解决方案2】:

    大汗淋漓之后,我得到了它:

    context.tsx

    import React, { FC } from 'react'
    import Reducer from './reducer'
    
    
    type LoadContextType = {
      load: boolean 
      setLoad: (load: boolean) => void
    }
    
    const InitialState = {
      load: true
    }
    
    export const LoadContext = React.createContext<LoadContextType | null>(null)
    
    export const LoadProvider: FC = ({ children }) => {
      const [state, dispatch] = React.useReducer(Reducer, InitialState)
    
      const setLoad = (load: boolean): void => dispatch({ type: 'set_load', load })
    
      return (
        <LoadContext.Provider value={{ load: state.load, setLoad }}>
          {children}
        </LoadContext.Provider>
      )
    }
    
    export const useLoadContext = (): LoadContextType => React.useContext(LoadContext) as LoadContextType
    

    reducer.tsx

    interface stateProps {
      load: boolean 
    }
    
    interface actionProps extends stateProps {
      type: string
    }
    
    export default (state: stateProps, action: actionProps): stateProps => {
      switch (action.type) {
        case 'set_load':
          return {
            load: action.load
          }
        default:
          return state
      }
    }
    

    index.tsx

    import React from 'react'
    import ReactDom from 'react-dom'
    import '@styles/styles.scss'
    
    import { LoadProvider } from '@src/context/LoadContext'
    import { App } from '@components/app'
    ReactDom.render(
    <LoadProvider>
      <App />
    </LoadProvider>
    , document.getElementById('root'))
    

    App.tsx

    import React, { ReactElement } from 'react'
    import { useLoadContext } from '@src/context/LoadContext'
    
    export const App = (): ReactElement => {
      const { load } = useLoadContext()
      console.log(load);
      
      return <h1>Getting context provider to work on TypeScript</h1>
    }
    

    【讨论】:

      猜你喜欢
      • 2020-11-01
      • 1970-01-01
      • 2019-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多