是否有新的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);
但是有没有一种方法可以导出一些带有钩子的函数,这些钩子将具有状态并与任何想要获取数据的组件共享配置文件?
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,否则不会共享它;
更新:
我之前的回答是-你可以使用useState的自定义挂钩来达到这个目的,但由于这个事实,这是错误的:
使用相同Hook的两个组件共享状态吗No。自定义挂钩是一种重用有状态逻辑的机制(例如设置订阅和记住当前值(,但每次使用自定义挂钩时,它内部的所有状态和效果都是完全隔离的。
ShubhamKhatri 提供的useContext((的正确答案
现在我这样使用它。
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>
}