7.Next.js14 组件之Context组件共享组件数据

7.Next.js14 组件之Context组件共享组件数据

Context组件共享组件数据

Context API在React以及Next.js中是一种非常强大的状态管理工具,它可以实现在组件间共享数据。通过使用Context,我们可以避免将prop逐级传递,而是让组件直接访问所需的数据。

需要注意的是,Context 只能在客户端组件中使用

在Next.js 14中,使用React的Context API的基本步骤如下:

创建一个Context

首先,我们需要使用React的createContext函数来创建一个新的Context。这将返回一个Context对象,我们可以在后续的任何地方使用这个对象。

import React from 'react';
const MyContext = React.createContext(defaultValue);

在上述代码中,defaultValue是一个可选参数,它将会在组件没有找到匹配的Provider时被使用。

创建Context Provider

Context对象创建完成后,我们可以通过它提供的Provider组件来提供数据。我们可以将任何数据(例如状态、函数、对象等)作为value传递给Provider

<MyContext.Provider value={/* some value */}>
  <SomeComponent />
</MyContext.Provider>

在上述代码中,所有在MyContext.Provider内部的组件都可以访问到当前Context的值。

在组件中使用Context

我们可以使用useContext钩子函数来在函数组件中使用Context

import React, { useContext } from 'react';

function SomeComponent({
  const contextValue = useContext(MyContext);

  // 现在可以在组件中使用 contextValue
}

在上述代码中,useContext函数接收一个Context对象,并返回当前Context的值。

具体的写个列子

首先,在项目目录的根目录下创建一个名为 “context” 的目录,并在其中创建一个名为 “CounterProvider.tsx” 的文件。为了配置客户端组件,需要在文件的顶部添加 use client 的设置。

//context/CounterProvider.tsx
'use client';
import React from "react";

const CounterContext = React.createContext<[number,React.Dispatch<React.SetStateAction<number>>] | undefined>(undefined);

export function CounterProvider({children}:{children:React.ReactNode}){
    const [count,setCount] = React.useState(0)
    return (
        <CounterContext.Provider value={[count,setCount]}>
            {children}
        </CounterContext.Provider>

    )
}

export function useCounter({
    const context = React.useContext(CounterContext)
    if (context === undefined){
        throw new Error('useCounter 必须在 CounterProvider 中使用')
    }
    return context
}

看以上的代码:

  1. 我们定义一个名为CounterContext的上下文对象,并指定了该上下文的初始值为 undefined

    • 第一个元素是一个 number 类型,表示计数器的值。
    • 第二个元素是一个 React.Dispatch<React.SetStateAction<number>> 类型,它是一个用于更新计数器值的React状态更新函数的类型。
    • React.createContext(...): 这是React的上下文创建函数。它创建了一个新的上下文对象,并允许在该上下文中存储和共享数据。

    • <...>: 这是 TypeScript 的泛型语法,用于指定上下文对象的值的类型。在这里,它指定了上下文值的类型为一个数组,该数组包含两个元素:

    • | undefined: 这表示上下文的初始值可以是一个包含上述类型的数组,或者是 undefined。这是因为在使用上下文时,初始值可能没有被提供,所以初始值是可选的。

    • CounterProvider 的组件,它接受一个 children 属性,该属性用于渲染嵌套在 CounterProvider 内部的子组件。这个组件的主要作用是提供计数器状态给其子组件。

    • 在组件内部,使用React.useState(0)创建了一个名为 count 的状态变量,初始值为 0

    • 然后,使用 CounterContext.Provider 来包裹子组件,并通过 value 属性将 [count, setCount] 传递给上下文,从而使子组件能够访问和修改计数器状态。

    1. useCounter 用于在React组件中访问计数器状态和更新函数。
    • React.useContext(CounterContext) 用于获取当前上下文中存储的值,也就是 [count, setCount] 数组。

    • 如果上下文值为 undefined,则抛出一个错误,提示用户必须在 CounterProvider 内部使用此Hook,以确保上下文值可用。

    使用

    将创建好的CounterProvider导入到app目录下的layout.tsx文件中。

    //app/layout.tsx
    import './globals.css'
    import type { Metadata } from 'next'
    import { Inter } from 'next/font/google'
    import {CounterProvider} from "@/context/CounterProvider";

    const inter = Inter({ subsets: ['latin'] })

    export const metadata: Metadata = {
      title'Create Next App',
      description'Generated by create next app',
    }

    export default function RootLayout({
        children
    }: {
        children: React.ReactNode
    }
    {
      return (
        <html lang="en">
          <body className={inter.className}>
          
          <CounterProvider>{children}</CounterProvider>
          
          </body>
        </html>

      )
    }

    上下文设置完成。由于Context是在RootLayout中完成的,所以Context可以在app下的客户端组件中使用。

    修改Counter.tsx

    //app/components
    'use client'
    import React, {useState} from "react";
    import { useCounter } from '@/context/CounterProvider'
    export default function Counter({children}:{
        children:React.ReactNode
    }
    {
        //const [count,setCount] = useState<number>(0)
        //从CounterProvider中获取
        const [count,setCount] = useCounter()
        const increment = () => {
          setCount((pre) => pre + 1)
        }
        return(
            <>
                <div>Count:{count}</div>
                <button onClick={increment} className="px-2 py-1 rounded-lg bg-blue-600 text-white">Increment</button>
                {children}
            </>

        )
    }

    效果跟之前的一样,使用 Context 增加 Count 的值。7.Next.js14 组件之Context组件共享组件数据

    如果文章对你有用,请点个关注,一起学习吧!



    原文始发于微信公众号(大前端编程教学):7.Next.js14 组件之Context组件共享组件数据

    版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

    文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/224386.html

    (0)
    小半的头像小半

    相关推荐

    发表回复

    登录后才能评论
    极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!