javascript - 将组件状态传递给 next.js 中应用程序的所有组件的 Props 替代方法
问题描述
我想将setState
组件(SnackBar
)的方法传递给_app.js
. 如果我将 SnackBar 的 setState 方法传递给 _app.js 的所有子组件,那么这将是一项非常繁琐的任务。因为,从 _app.js 到单个组件节点大约有 4 个层次结构。这包括,
_app.js -> pages -> layouts -> sections -> components
_app.js 的片段在这里。
function MyApp({ Component, pageProps }) {
const [ toastOpen, setToastOpen ] = React.useState({
msg: '',
open: false
});
React.useEffect(() => {
pageProps = { ...pageProps, setToastOpen };
}, []);
return (
<React.Fragment>
<ToastMessage
message={ toastOpen.msg }
setOpenState={ setToastOpen }
openState={ toastOpen.open }
/>
<Component {...pageProps} />
</React.Fragment>
)
}
有什么方法可以直接导入setToastOpen
子组件中的方法并在需要时使用它?
解决方案
React 有一个称为 Context Api 的特殊功能,使用它您可以跳过传递给组件的 props 链。
我建议您查看以下资源以了解上下文 Api -
ContextAPI 示例
为 Context 创建一个单独的文件Toast-context.js
,您可以使用任何您想要的名称。
import React, { useState } from "react"
const ToastContext = React.createContext({
message: "",
toastOpen: false,
toggleToast: () => { },
changeMessage: () => { }
})
export const ToastContextProvider = ({children}) => {
/*you need to use
this component to wrap App.js so that the App.js and all of its children
and their children components and so on will get the access to the
context*/
const [toastOpen, setToastOpen] = useState(false);
const [message, setMessage] = useState("");
const toggleToast = () => {
setToastOpen(true)
}
const changeMessage = (message) => {
setMessage(message);
}
return (
<ToastContext.Provider value={
toastOpen,
message,
toggleToast,
changeMessage
}>
{children}
</ToastContext.Provider>
)
}
现在在
App.js
文件中你需要用 ToastContextProvider 组件包装你的组件
import React, { useContext } from "react";
import { ToastContextProvider } from "./Toast-context";
import { ToastContext } from "./Toast-context";
function MyApp({ Component, pageProps }) {
const { message, toastOpen, toggleToast, changeMessage } =
useContext(ToastContext);
return (
<ToastContextProvider>
{toastOpen && <div className="toast">{message}</div>}
</ToastContextProvider>
);
}
只需在您想要的任何组件中使用 useContext Hook 导入上下文。你不需要<ToastContextProvider>
在每个组件中包装。只需使用 useContext 钩子,然后您就可以看到状态并调用函数方法来更改状态。
还要确保参考上述链接以了解有关 Context Api 的更多信息。谢谢你
推荐阅读
- swiftui - 手动从子视图到父视图以及从拖动中解散时如何修复导航栏标题重叠?
- javascript - 用数组过滤对象
- javascript - 如何确定以下 JavaScript 代码为什么会插入两次计时器记录?
- winforms - Winforms PropertyGrid 没有类别
- r - 根据行值添加特定列值
- python - Python为图像中断PNG添加噪声
- r - R中数据包络分析的优势
- postgresql - 带有 DataGrip 的 PostgreSQL - “表不存在”
- c# - 如何在 C# 的 linq 查询中 sql 查询包含行号?
- assembly - 在程序集中为 sys_create 和 sys_write 指定文件路径