6

有没有办法用新的反应钩子 API 来替换上下文数据获取?

如果您需要加载用户配置文件并几乎在任何地方使用它,首先您创建上下文并导出它:

export const ProfileContext = React.createContext()

然后导入顶级组件,加载数据并使用提供程序,如下所示:

import { ProfileContext } from 'src/shared/ProfileContext'

<ProfileContext.Provider
      value={{ profile: profile, reloadProfile: reloadProfile }}
    >
        <Site />
    </ProfileContext.Provider>

然后在其他一些组件中导入配置文件数据,如下所示:

import { ProfileContext } from 'src/shared/ProfileContext'
const context = useContext(profile);

但是有一种方法可以使用钩子导出一些函数,这些钩子将具有状态并与任何想要获取数据的组件共享配置文件?

4

3 回答 3

7

React 提供了一个 useContext 钩子来使用 Context,它有一个类似的签名

const context = useContext(Context);

useContext接受一个上下文对象(从 React.createContext 返回的值)并返回当前上下文值,由给定上下文的最近上下文提供者给出。

当提供程序更新时,此 Hook 将触发具有最新上下文值的重新渲染。

您可以在组件中使用它,例如

import { ProfileContext } from 'src/shared/ProfileContext'

const Site = () => {
   const context = useContext(ProfileContext);
   // make use of context values here
}

但是,如果您想在每个组件中使用相同的上下文并且不想在ProfileContext任何地方导入,您可以简单地编写一个自定义钩子,例如

import { ProfileContext } from 'src/shared/ProfileContext'
const useProfileContext = () => {
   const context = useContext(ProfileContext);
   return context;
}

并在组件中使用它

const Site = () => {
   const context = useProfileContext();
}

然而,就创建一个在不同组件之间共享数据的钩子而言,Hooks 有一个自己的数据实例,除非您使用 Context,否则不会共享它;

于 2018-11-04T09:20:27.750 回答
2

更新:

我之前的回答是 - 您可以为此目的使用带有 useState 的自定义钩子,但由于这个事实,这是错误的:

使用相同 Hook 的两个组件是否共享状态?不会。自定义 Hook 是一种重用有状态逻辑的机制(例如设置订阅和记住当前值),但是每次使用自定义 Hook 时,其中的所有状态和效果都是完全隔离的。

正确答案如何使用提供的 useContext() @ShubhamKhatri

于 2018-11-02T14:48:46.347 回答
0

现在我像这样使用它。

Contexts.js - 从一处导出所有上下文

export { ClickEventContextProvider,ClickEventContext} from '../contexts/ClickEventContext'
export { PopupContextProvider, PopupContext } from '../contexts/PopupContext'
export { ThemeContextProvider, ThemeContext } from '../contexts/ThemeContext'
export { ProfileContextProvider, ProfileContext } from '../contexts/ProfileContext'
export { WindowSizeContextProvider, WindowSizeContext } from '../contexts/WindowSizeContext'

ClickEventContext.js - 上下文示例之一:

import React, { useState, useEffect } from 'react'

export const ClickEventContext = React.createContext(null)
export const ClickEventContextProvider = props => {
  const [clickEvent, clickEventSet] = useState(false)
  const handleClick = e => clickEventSet(e)

  useEffect(() => {
    window.addEventListener('click', handleClick)
    return () => {
      window.removeEventListener('click', handleClick)
    }
  }, [])

  return (
    <ClickEventContext.Provider value={{ clickEvent }}>
      {props.children}
    </ClickEventContext.Provider>
  )
}

导入和使用:

import React, { useContext, useEffect } from 'react'
import { ClickEventContext } from 'shared/Contexts'

export function Modal({ show, children }) {
  const { clickEvent } = useContext(ClickEventContext)

  useEffect(() => {
    console.log(clickEvent.target)
  }, [clickEvent])

  return <DivModal show={show}>{children}</DivModal>
}
于 2019-02-19T14:27:16.157 回答