wha*_*wee 9 javascript reactjs gatsby
我是 React 的新手,目前我正在 Gatsby 站点上工作,在那里我有一个 Layout.js(Parent) 和 Menu.js(Child),当 Menu 上的状态发生变化时,我希望它传递给 Layout.js .
我想要做的是当菜单处于活动状态时,布局中的文本会发生变化。
菜单.js
import React, {useState, createContext} from "react"
const MenuContext = createContext(1)
const Menu = (props) => {
const [active, setActive] = useState(1)
const clickHandler = () => {
setActive(!active);
}
return(
<div className={(active ? `open` : `close`)} onClick={clickHandler}></div>
)
}
export { Menu, MenuContext }
Run Code Online (Sandbox Code Playgroud)
布局.js
import React, {useContext} from "react"
import { Menu, MenuContext } from "../components/menu"
const Layout = ({ children }) => {
const menuActive = useContext(MenuContext)
return (
<>
<h1 style={{color:`#fff`}}>{(menuActive) ? `Menu Opened` : `Menu Closed`}</h1>
<main>{children}</main>
<Menu />
</>
)
}
export default Layout
Run Code Online (Sandbox Code Playgroud)
似乎menuActive总是打印 1。我可以确保 Menu.js 中的状态工作正常,但我不知道如何将状态传递给 Layout.js。
请大家给点建议,谢谢!
Shu*_*tri 12
在尝试访问上下文值之前,您需要有一个包装您的应用程序的 Provider。为了拥有一个全局和单一的提供者,你需要wrapRootElement从 gatsby-browser.js 文件中导出实例。它看起来像
菜单上下文.js
import React, { createContext, useState } from "react"
export const MenuContext = createContext()
export const MenuProvider = ({ children }) => {
const [active, setActive] = useState(true);
return (
<MenuContext.Provider value={{active,setActive}}>
{children}
</MenuContext.Provider>
);
};
Run Code Online (Sandbox Code Playgroud)
gatsby-browser.js
import React, { useState } from 'react';
import MenuContext from './src/context/MenuContext';
const wrapRootElement = ({ element }) => {
return (
<MenuProvider>
{element}
</MenuProvider>
);
};
export { wrapRootElement }
Run Code Online (Sandbox Code Playgroud)
现在你可以在Layoutlike 中使用它
import React, { useContext } from "react"
import { Menu } from "../components/menu"
import { MenuContext } from '../menuContext';
const Layout = ({ children }) => {
const {active} = useContext(MenuContext)
return (
<>
<h1 style={{color:`#fff`}}>{(active) ? `Menu Opened` : `Menu Closed`}</h1>
<main>{children}</main>
<Menu />
</>
)
}
export default Layout
Run Code Online (Sandbox Code Playgroud)
在Menu你的内心会有
import React, { useContext } from "react"
import { MenuContext } from '../context/MenuContext';
const Menu = (props) => {
const {active, setActive} = useContext(MenuContext)
const clickHandler = () => {
setActive(!active);
}
return(
<div className={(active ? `open` : `close`)} onClick={clickHandler}></div>
)
}
export { Menu }
Run Code Online (Sandbox Code Playgroud)
注意:您需要从单独的文件中创建和导出上下文以避免任何循环依赖
但是,如果您只是通过将状态提升到 Layout 组件来在布局和菜单之间进行通信,则可以在不使用上下文的情况下完成您想要实现的目标
菜单.js
import React from "react"
const Menu = ({clickHandler, active}) => {
return(
<div className={(active ? `open` : `close`)} onClick={clickHandler}></div>
)
}
export { Menu }
Run Code Online (Sandbox Code Playgroud)
布局.js
import React, {useState} from "react"
import { Menu } from "../components/menu"
const Layout = ({ children }) => {
const [active, setActive] = useState(1)
const clickHandler = () => {
setActive(!active);
}
return (
<>
<h1 style={{color:`#fff`}}>{(menuActive) ? `Menu Opened` : `Menu Closed`}</h1>
<main>{children}</main>
<Menu clickHandler={clickHandler} active={active}/>
</>
)
}
export default Layout
Run Code Online (Sandbox Code Playgroud)