【问题标题】:Use multiple 'useContext' in one React component在一个 React 组件中使用多个“useContext”
【发布时间】:2020-10-24 10:59:28
【问题描述】:

在一个 React 组件中使用多个“useContext”钩子是一种好的,甚至是传统的方法。通常我会像这样从提供者那里提取状态和调度:

const { state, dispatch } = useContext(thisIsTheContext);

当然,这意味着我在上下文本身中定义了statedispatch

现在我读到一些人制作了一种“rootContext”,您可以在其中通过一个 Provider 传递所有状态。但是,这对我来说似乎有点矫枉过正。

当然我可以用不同的方式命名statedispatch,但是,我认为在使用useReducer 挂钩时只使用这两个是惯例。

任何人都可以对此有所了解吗?


编辑(根据要求 App.js 组件的外观):

function App() {
  return (
    <FlightDataProvider>
      <TravellerProvider>
        <Component /> // component here
      </TravellerProvider>
    </FlightDataProvider>
  );
}

【问题讨论】:

  • 你能分享你的 App.js 根组件,你提供多个上下文吗?
  • @onuriltan 我在帖子中添加了我的 App.js:它归结为几个供应商包装了所有应用程序组件。
  • 您能否也分享一个您的 Provider,将有助于了解您如何传递值和调度
  • 发布了一个答案,看看你是否还有问题

标签: reactjs react-context


【解决方案1】:

我认为不需要rootContext。我所做的是在特定的Context Provider 中定义useReducer。我为特定上下文提供状态和函数,如下所示。

FlightDataProvider.js

import React, { useReducer, createContext } from 'react'

const flightDataReducer = (state, action) => {
  switch (action.type) {
    case 'SET_FLIGHT_DATA':
      return {
        ...state,
        flightData: action.payload,
      }
    default:
      return state
  }
}

export const FlightDataContext = createContext();

export const FlightDataProvider = props => {
  const initialState = {
    flightData: 'flightData'
  }

  const [state, dispatch] = useReducer(flightDataReducer, initialState)

  const setFlightData = newFlightData => {
    dispatch({ type: 'SET_FLIGHT_DATA', payload: newFlightData })
  }

  return (
    <FlightDataContext.Provider
      value={{
        flightData: state.flightData,
        setFlightData
      }}>
      {props.children}
    </FlightDataContext.Provider>
  )
}

之后,如果我想在同一个组件中订阅两个不同的上下文,我喜欢这样;

SomeComponent.js

import React from 'react'
import { FlightDataContext } from '...'
import { AnotherContext } from '...'

export const SomeComponent = () => {
  const { 
    flightData,
    setFlightData
  } = useContext(FlightDataContext)

  const {
    someValue
    setSomeValue
  } = useContext(AnotherContext)

  return (...)
}

PS你可能想要分离flightDataReducer函数,将它移动到另一个js文件中并导入到FlightDataProvider.js

【讨论】:

    【解决方案2】:

    如果我理解您的问题,您担心在一个 react 组件中拉入多个上下文时如何克服名称冲突,因为在它们的原始文件中,它们都是具有相同属性“调度”的对象。

    您可以使用 es6 解构的一个方面来重命名组件内部的差异上下文对象属性。

    像这样:

    const { user, despatch: setUser } = useContext(UserContext);
    const { theme, despatch: setTheme } = useContext(ThemeContext);
    const { state, despatch: setState } = useReducer(reducer);
    

    我随意选择了名称 setUser、setTheme 和 setState。你可以使用任何你喜欢的名字。

    【讨论】:

      猜你喜欢
      • 2021-07-04
      • 1970-01-01
      • 1970-01-01
      • 2022-06-13
      • 2018-02-06
      • 2021-06-19
      • 1970-01-01
      • 1970-01-01
      • 2018-12-02
      相关资源
      最近更新 更多