在一个 React 组件中使用多个“useContext”

Posted

技术标签:

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

钩子是一种好的,甚至是传统的方法。通常我会像这样从提供者那里提取状态和调度:

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,将有助于了解您如何传递值和调度 发布了一个答案,看看你是否还有问题 【参考方案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。你可以使用任何你喜欢的名字。

【讨论】:

以上是关于在一个 React 组件中使用多个“useContext”的主要内容,如果未能解决你的问题,请参考以下文章

React.js + Reactstrap 多个模态在一个组件中

React-Redux 中同一组件的多个实例

如何在同一个 React 组件中管理多个 setState 调用?

使用react Context(Ionic-React)时未定义history.push()[重复]

无法在 react native 中使用 redux 连接多个组件

在 React 组件中的多个 GraphQL 查询之间进行更改