文章目录
-
- 一.前置知识
- 二.代码实现
-
- 目录结构
- 1.创建`ContentProvider`组件
- [2.使用封装的`ContentProvider`组件 + `useEventContext`钩子函数](#2.使用封装的
ContentProvider
组件 +useEventContext
钩子函数) - 3.嵌套层级的函数组件 (这部分意义不大,只是为了展示嵌套层级)
- 4.最底层的函数组件
- 三.效果展示
- 四.总结
一.前置知识
createContext
简介createContext
是 React 提供的一个用于创建上下文(Context)的函数。上下文是一种在组件树中共享数据的方式,它允许你将数据传递给多个组件,而不必通过组件树的每一层手动传递props
。这在处理一些全局状态(如主题、用户认证信息等)时非常有用。- 当你调用
createContext
时,它会返回一个包含两个属性的对象:Provider
和Consumer
(在使用函数组件和useContext
钩子时,Consumer
的使用方式被简化了)。Provider
是一个组件,用于提供数据给它的后代组件;Consumer
是一个用于订阅Provider
提供的数据的组件(在使用useContext
时这个过程更简单)。
useContext
简介useContext
是一个 React 钩子,它用于在函数组件中订阅由createContext
创建的上下文。通过useContext
,函数组件可以轻松地访问到在组件树中上层Provider
组件提供的数据,使得在组件树中共享数据变得更加方便和简洁。- 它接收一个上下文对象(由
createContext
创建的)作为参数,并返回该上下文的当前值。这样,组件就可以根据这个值来进行渲染或其他操作。
二.代码实现
目录结构
js
|------ pages
|------------ ContentProVider
|--------------------- index.jsx
|--------------------- ContentProvider.jsx
|--------------------- one.jsx
|--------------------- two.jsx
|--------------------- three.jsx
|--------------------- four.jsx
|--------------------- five.jsx
1.创建ContentProvider
组件
ContentProvider.jsx
封装
createContext
,useContext
使用
jsx
// 引入 React 的 createContext 和 useContext 方法,以及 useState 钩子
import { createContext, useContext, useState } from 'react'
// 创建一个 EventContext 的上下文对象,初始值为空对象
const EventContext = createContext({})
/**
* useEventContext 是一个自定义钩子,用于获取 EventContext 的当前值。
*/
export const useEventContext = () => useContext(EventContext)
/**
* ContentProvider 是一个组件,用于提供 EventContext 的值。
* 这个组件提供为了封装 EventContext 的值,并且可以在整个组件中共享。
*/
export const ContentProvider = ({ children }) => {
const [count, setCount] = useState(0)
const [data, setData] = useState('null')
// updateData 是一个函数,用于更新 data 状态变量的值为当前时间戳。
const updateData = () => {
setData(new Date().getTime())
}
return (
// 使用 EventContext.Provider 组件提供 count、setCount、data 和 updateData 的值
<EventContext.Provider
value={{
count,
setCount,
data,
updateData
}}
>
{children}
</EventContext.Provider>
)
}
2.使用封装的ContentProvider
组件 + useEventContext
钩子函数
顶层组件
jsx
import { useEventContext, ContentProvider } from './ContentProvider'
import OnePage from './one'
/**
* CreateContent 组件作为顶层组件使用
* 使用 useEventContext 钩子函数来获取上下文数据和方法,在页面上显示和操作这些数据。
*/
const CreateContent = () => {
// 使用 useEventContext 钩子函数获取上下文数据和方法
const { count, setCount, data, updateData } = useEventContext()
return (
<div style={{ display: 'flex', flexDirection: 'column' }}>
<div style={{ borderBottom: '1px solid black', marginBottom: 10, paddingBottom: 10 }}>
{count}
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>{count}</button>
</div>
<div onClick={() => updateData()}>更新数据</div>
<div>{data}</div>
<hr />
<div style={{ marginLeft: 25 }}>
<OnePage />
</div>
</div>
)
}
/**
* CreateContentPage 组件是一个 React 函数组件,用于创建内容页面。
* 它使用 ContentProvider 组件来提供上下文,并在其内部渲染 CreateContent 组件。
*
* @returns {JSX.Element} 返回一个包含 CreateContent 组件的 JSX 元素。
*/
const CreateContentPage = () => {
// 使用 ContentProvider 组件来提供上下文
return (
<ContentProvider>
<CreateContent />
</ContentProvider>
)
}
export default CreateContentPage
3.嵌套层级的函数组件 (这部分意义不大,只是为了展示嵌套层级)
jsx
// one.jsx
import TwoPage from './two'
/**
* OnePage 组件用来嵌套组件,用于展示第一层子组件。
* 展示一个标题和一个嵌套的 TwoPage 组件。
*/
const OnePage = () => {
return (
<div>
<h1>第一层子组件</h1>
<div style={{ marginLeft: 25 }}>
{/* 渲染 TwoPage 组件 */}
<TwoPage />
</div>
</div>
)
}
export default OnePage
jsx
// two.jsx
import ThreePage from './three'
const TwoPage = () => {
return (
<div>
<h1>第二层子组件</h1>
<div style={{ marginLeft: 25 }}>
<ThreePage />
</div>
</div>
)
}
export default TwoPage
jsx
// three.jsx
import FourPage from './four'
const ThreePage = () => {
return (
<div>
<h1>第三层子组件</h1>
<div style={{ marginLeft: 25 }}>
<FourPage />
</div>
</div>
)
}
export default ThreePage
jsx
import FivePage from './five'
const FourPage = () => {
return (
<div>
<h1>第四层子组件</h1>
<div style={{ marginLeft: 25 }}>
<FivePage />
</div>
</div>
)
}
export default FourPage
4.最底层的函数组件
jsx
// 导入 useEventContext 钩子
import { useEventContext } from './ContentProvider'
/**
* FivePage 组件是最底部组件,用于展示和更新上下文数据。
* 使用 useEventContext 钩子来获取上下文数据,并在页面上展示和更新这些数据。
*
*/
const FivePage = () => {
// 使用 useEventContext 钩子获取上下文数据
const { count, setCount, data } = useEventContext()
return (
<div style={{ display: 'flex', flexDirection: 'column' }}>
<div style={{ borderBottom: '1px solid black', marginBottom: 10, paddingBottom: 10 }}>
{count}
<h1>{count}</h1>
{/* 点击按钮增加 count 的值 */}
<button onClick={() => setCount(count + 1)}>{count}</button>
</div>
<div>{data}</div>
<hr />
</div>
)
}
export default FivePage
三.效果展示
四.总结
通过对 React 中 createContext 和 useContext 的深入学习和实践,我们能够有效地在组件树中共享数据,避免了繁琐的 props 层层传递。在实际应用中,合理地使用上下文可以提高代码的可维护性和可读性,尤其是在处理全局状态或需要在多个组件间共享的数据时。同时,通过对代码的优化,我们进一步提升了性能和代码质量,使得应用在运行时更加高效和稳定。