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
}
看以上的代码:
-
我们定义一个名为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]
传递给上下文,从而使子组件能够访问和修改计数器状态。
-
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组件共享组件数据
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/224386.html