reactjs - 上下文有问题
问题描述
我了解上下文和在不进行道具钻探的情况下传递状态的能力(老实说,这似乎是相同数量的工作......我使用 redux 进行全局状态管理,除了样板之外,还可以使用 reducer、action creator 和redux 开发工具让我觉得它更有用)
即使使用 useContext 钩子,所需的代码量实际上与对我来说只是道具钻孔一样烦人......但也许我错过了一些东西
除了所有这些......我目前正在尝试拥有一个简单的导航栏功能,当打开汉堡菜单时,主页的背景会变成褪色的较暗不透明度。我不想要图书馆。我喜欢自己做这一切。
这是我的应用程序文件。我假设我可以将状态向下传递(打开),这将指示导航是否打开。但是,如果我唯一可以通过的是打开而不是 setOpen,我该如何更改打开状态...我不能在整个导航栏组件上设置 onClick 事件。我需要 onclick 甚至在导航中,但传递的只是状态本身。每次我认为我理解反应时,都会出现一些新的独特情况,我遇到类似的状态问题
// components
import Nav from './components/Nav'
import Homepage from './components/Homepage'
import React, {useState, createContext} from "react";
import {
BrowserRouter as Router,
Route,
} from "react-router-dom";
// pages
import About from './components/pages/About'
import Stories from './components/pages/Stories'
import News from './components/pages/News'
import ThemeContext from './ThemeContext';
// imports
function App() {
const [open, setOpen]=useState(false)
return (
<>
<Router>
<ThemeContext.Provider value={open}>
<Nav />
<Route path='/' exact>
<Homepage />
</Route>
<Route path='/about' component={About} exact />
<Route path='/stories' component={Stories} exact />
<Route path='/news' component={News} exact />
</ThemeContext.Provider>
</Router>
</>
);
}
export default App;
这是我的导航组件
import React, {useEffect, useState, useContext, useRef} from 'react'
import '../styles/custom.css'
import MenuDrop from './MenuDrop.js'
import {Link} from 'react-router-dom'
import ThemeContext from '../ThemeContext.js'
const Nav = () => {
const [active, setActive]=useState(false)
const [touched, setTouched]=useState(false)
const myRef=useRef()
const open=useContext(ThemeContext)
const clicker=()=>{
if(window.innerWidth<450){
setActive(!active);
}
}
useEffect(()=>{
console.log(open)
},[active])
const toucher=()=>{
setTouched(true);
}
const toucherOff=()=>{
setTouched(false);
}
return (
/* NAVBAR */
<>
<div className={`shadow-xl ${open?'dark':'light'}`}>
<div className='nav c overflow-hidden w-full nav-main md:pt-8 pt-4 flex justify-between md:justify-around items-center flex-row flex-shadow-2xl'>
<h1 className=' mx-2 antialiased text-lg md:text-3xl font-bold text-green-700 font-second-bold'>HUNTER SOLICITERS</h1>
<div className={`${active?'nav-items-active':'nav-items'} bg-white items-center md:items-center flex flex-col justify-center md:flex-row md:justify-around list-none w-1/3 flex-shadow-2xl`}>
<Link onClick={()=>setActive(false)} to='/about' className='lg:mt-0 mt-20 text-green-800 hover:text-green-800 font-semibold duration-200 antialiased p-2 cursor-pointer lg:my-0 my-6 text-sm lg:hover:text-white lg:hover:bg-red-900 font-main'>About</Link>
<li onClick={()=>setActive(false)} className='text-green-800 hover:text-green-800 font-semibold duration-200 antialiased p-2 cursor-pointer lg:my-0 my-6 text-sm lg:hover:text-white lg:hover:bg-red-900 font-main'>Contact</li>
<Link onClick={()=>setActive(false)} to='/stories' className='lg:mt-0 text-green-800 hover:text-green-800 font-semibold duration-200 antialiased p-2 cursor-pointer lg:my-0 my-6 text-sm lg:hover:text-white lg:hover:bg-red-900 font-main'>Stories</Link>
<Link onClick={()=>setActive(false)} to='/news' className='lg:mt-0 text-green-800 hover:text-green-800 font-semibold duration-200 antialiased p-2 cursor-pointer lg:my-0 my-6 text-sm lg:hover:text-white lg:hover:bg-red-900 font-main'>News</Link>
<div onMouseLeave={()=>toucherOff()} onMouseEnter={()=>setTouched(true)} className='flex flex-row items-center'>
<li onClick={()=>setActive(false)} className='text-green-800 hover:text-green-800 font-semibold duration-200 antialiased p-2 cursor-pointer lg:my-0 my-6 text-sm lg:hover:text-white lg:hover:bg-red-900 font-main'>Team</li>
<svg className='hover:bg-red-900 text-black hover:text-white arrowTwo' xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</div>
</div>
<div onClick={()=>clicker()} ref={myRef} className={active?'mx-2 burger-active ':'burger mx-2'}>
<div className={active?'toggle1 line-one':'line-one'}></div>
<div className={active?' toggle2 line-two':'line-two'}></div>
<div className={active?' toggle3 line-three':'line-three'}></div>
</div>
</div>
<MenuDrop toucher={toucher} setTouched={setTouched} toucherOff={toucherOff} touched={touched}/>
</div>
</>
)
}
export default Nav
这是我的主页组件
import React, {useContext, useEffect} from 'react'
// COMPONENTS
import Banner from './Banner'
import Footer from './Footer'
import GreenBanner from './GreenBanner'
import HomepageContentCards from './HomepageContentCards'
import HomepageContent from './HomepageContent'
import HomepageTeam from './HomepageTeam'
import WrappedMap from './Map'
import ThemeContext from '../ThemeContext'
import '../styles/custom.css'
// ASSETS
import imageTwo from '../images/home-image-two.jpg'
import imageThree from '../images/home-image-three.jpg'
import imageFour from '../images/home-image-four.jpg'
const Homepage = () => {
useEffect(()=>{
window.scrollTo(0, 0);
console.log(open)
})
const open=useContext(ThemeContext)
return (
<div className={`${open==='false'?'mt-0':'mt-20'} bg-container mt-10 md:mt-0 shadow-2xl`}>
<Banner />
<div className='shadow-xl grid grid-cols-1 gap-0 lg:gap-0 lg:grid-cols-12'>
<div class=" col-span-7">
<HomepageContent />
</div>
<div class="">
<HomepageTeam />
</div>
</div>
<GreenBanner />
<div className='grid grid-cols-1 gap-2 lg:gap-3 sm:grid-cols-3'>
<HomepageContentCards image={imageTwo}/>
<HomepageContentCards image={imageThree} />
<HomepageContentCards image={imageFour} />
</div>
<div className='mt-8 lg:mt-0'>
<WrappedMap
isMarkerShown
googleMapURL={`https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places$key=${process.env.REACT_APP_GOOGLE_KEY}`}
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `400px` }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
</div>
<Footer />
</div>
)
}
export default Homepage
我正在使用顺风,所以忽略所有的类等。基本上我试图有一个简单的状态(导航栏是否打开并且汉堡是否已被按下打开它)....如果它打开了其余的背景东西(主页)通过使用条件渲染变为褪色不透明度的深色-->open?'dark':'light'
我可以向下传递状态,但是如果在上述父组件(App)中创建了状态和挂钩,我如何从挂钩向下传递函数(setOpen)或者如何从子组件更改状态
我发誓反应让状态管理有时对我来说很愚蠢
解决方案
推荐阅读
- android - 当我将对象从片段发送到另一个片段时,原始数据已更新
- java - 如果两个复选框的语句被选中问题
- swift - 如何在 swift 中根据大小使用不同的 modalPresentationStyles?
- python - 如何以文本而不是 HTML 格式显示通过 TinyMCE 输入的数据?
- design-patterns - 这是分层架构模式的正确实现吗?
- javascript - 如何在 javascript 的 sublime text 3 中获取用户的输入?
- docker - 如何代理 docker compose 容器?
- r - 使用 dplyr group_split 保留数据帧名称
- linux - 写入文件时如何确定页面(缓存)边界
- android - 自动将私有应用程序发送给客户端