自学内容网 自学内容网

React 中 createContext 和 useContext 的深度应用与优化实战

一.前置知识

  1. createContext简介
    • createContext是 React 提供的一个用于创建上下文(Context)的函数。上下文是一种在组件树中共享数据的方式,它允许你将数据传递给多个组件,而不必通过组件树的每一层手动传递props。这在处理一些全局状态(如主题、用户认证信息等)时非常有用。
    • 当你调用createContext时,它会返回一个包含两个属性的对象:ProviderConsumer(在使用函数组件和useContext钩子时,Consumer的使用方式被简化了)。Provider是一个组件,用于提供数据给它的后代组件;Consumer是一个用于订阅Provider提供的数据的组件(在使用useContext时这个过程更简单)。
  2. useContext简介
    • useContext是一个 React 钩子,它用于在函数组件中订阅由createContext创建的上下文。通过useContext,函数组件可以轻松地访问到在组件树中上层Provider组件提供的数据,使得在组件树中共享数据变得更加方便和简洁。
    • 它接收一个上下文对象(由createContext创建的)作为参数,并返回该上下文的当前值。这样,组件就可以根据这个值来进行渲染或其他操作。

二.代码实现

目录结构

|—— pages
|———— ContentProVider
|——————— index.jsx
|——————— ContentProvider.jsx
|——————— one.jsx
|——————— two.jsx
|——————— three.jsx
|——————— four.jsx
|——————— five.jsx

1.创建ContentProvider组件

ContentProvider.jsx
封装 createContextuseContext使用

// 引入 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钩子函数

顶层组件

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.嵌套层级的函数组件 (这部分意义不大,只是为了展示嵌套层级)

// 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
// two.jsx
import ThreePage from './three'
const TwoPage = () => {
  return (
    <div>
      <h1>第二层子组件</h1>
      <div style={{ marginLeft: 25 }}>
        <ThreePage />
      </div>
    </div>
  )
}

export default TwoPage
// three.jsx
import FourPage from './four'
const ThreePage = () => {
  return (
    <div>
      <h1>第三层子组件</h1>
      <div style={{ marginLeft: 25 }}>
        <FourPage />
      </div>
    </div>
  )
}

export default ThreePage
import FivePage from './five'

const FourPage = () => {
  return (
    <div>
      <h1>第四层子组件</h1>
      <div style={{ marginLeft: 25 }}>
        <FivePage />
      </div>
    </div>
  )
}
export default FourPage

4.最底层的函数组件

// 导入 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 层层传递。在实际应用中,合理地使用上下文可以提高代码的可维护性和可读性,尤其是在处理全局状态或需要在多个组件间共享的数据时。同时,通过对代码的优化,我们进一步提升了性能和代码质量,使得应用在运行时更加高效和稳定。


原文地址:https://blog.csdn.net/cx18333/article/details/144738957

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!