我可以用钩子代替上下文吗?

时间:2018-11-02 14:18:47

标签: reactjs react-hooks

是否可以使用新的react hooks 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);

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

3 个答案:

答案 0 :(得分:5)

React提供了useContext钩子来使用Context,它具有类似

的签名
const context = useContext(Context);
  

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

     

提供商更新时,此挂钩将触发重新提交   最新的上下文值。

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

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();
}

但是,就创建一个在不同组件之间共享数据的钩子而言,钩子本身具有一个数据实例,除非您使用Context,否则不要共享它;

答案 1 :(得分:2)

已更新:

我以前的回答是-为此,您可以将use-hooks与useState一起使用,但这是错误的,因为这个事实:

  

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

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

答案 2 :(得分: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>
}