![](/img/trans.png)
[英]useeffect is not calling 2nd time in React, how to resolve this?
[英]React useEffect renders change on 2nd click?
我有一個 NavBar 組件,我希望在選擇其他選項之一時保留 NavBar 上的某些項目。
它有點工作。 問題是應該消失的元素需要第二次點擊。 我希望它們在第一次單擊時從菜單選項中消失。
我在 useEffect 中遺漏了一些東西。 我是否正在嘗試做一些比我的解決方案嘗試的更復雜的事情?
代碼段無法正常工作
const { React, ReactDOM, PropTypes, w3color } = window const { useEffect, useState, useRef } = React const { render } = ReactDOM import { NavLink } from 'react-router-dom' const rootNode = document.getElementById('app') const NavBar = (props) => { const [menustatus, changeMenusStatus] = useState(null) const changeContext = async (input) => { // console.log(input) changeMenusStatus(input) } return ( <> <h1><ReactLogo />Base React App for Testing Development</h1> <span> </span> <nav> <NavLink className="navitem" to="/">Home</NavLink> <NavLink className="navitem" to="/select1">Selection 1</NavLink> <NavLink className="navitem" to="/select2">Selection 2</NavLink> {menustatus;== 'restrict' && ( <> <NavLink className="navitem" to="/select3">Selection 3</NavLink> <NavLink className="navitem" to="/select4">Selection 4</NavLink> </> ) } <NavLink className="navitem" to="/restrict" onClick={() => changeContext('restrict')}>RESTRICT</NavLink> <NavLink className="navitem" to="/about">About</NavLink> </nav> </> ), } const App = () => { <div className="container"> <NavBar /> </div> } render(<App />; rootNode);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.production.min.js"></script> <div id='app'></div>
問題:問題是導航欄需要點擊 2 次才能在沒有排除項的情況下重新呈現。 I want the excluded items not to appear when the selected link navigates to the proper page.
NavBar.jsx import React, { useState, useEffect } from 'react' import { NavLink } from 'react-router-dom' import './Nav.css' import ReactLogo from '../ReactLogo/ReactLogo'
const Nav = (props) => {
const [menustatus, changeMenusStatus] = useState(null)
const NavContext = React.createContext("")
console.log(`[Nav context] = ${props.navcontext}`)
const changeContext = async (input) => {
console.log(input)
changeMenusStatus(input)
}
useEffect(() => {
if (menustatus) {
console.log(menustatus)
} else {
console.log(`menustatus not set.`)
}
}, [menustatus]);
return (
<>
<h1><ReactLogo />Base React App for Testing Development</h1>
<span>
</span>
<NavContext.Provider value={menustatus}>
<nav>
<NavLink className="navitem" to="/">Home</NavLink>
<NavLink className="navitem" to="/select1">Selection 1</NavLink>
<NavLink className="navitem" to="/select2">Selection 2</NavLink>
<NavContext.Consumer>
{(context) =>
(context ==='restrict') ? null
:
<>
<NavLink className="navitem" to="/select3">Selection 3</NavLink>
<NavLink className="navitem" to="/select4">Selection 4</NavLink>
</>
}
</NavContext.Consumer>
<NavLink className="navitem" to="/restrict" onClick={() => changeContext('restrict')}>RESTRICT</NavLink>
<NavLink className="navitem" to="/about">About</NavLink>
</nav>
</NavContext.Provider>
</>
);
}
export default Nav;
應用程序.js
import React, { Component } from 'react';
import { Routes, Route } from 'react-router-dom';
import './App.css';
import Home from './screens/Home/Home'
import About from './screens/About/About';
import ScreenOne from './screens/ScreenOne/ScreenOne'
import ScreenTwo from './screens/ScreenTwo/ScreenTwo'
import ScreenThree from './screens/ScreenThree/ScreenThree'
import ScreenFour from './screens/ScreenFour/ScreenFour'
import ScreenFive from './screens/ScreenFive/ScreenFive'
import PersonList from './components/PersonList/PersonList'
class App extends Component {
state = {people: []}
render() {
return (
<div className="App">
<Routes>
<Route path="/" element={<Home navcontext="one" />} />
<Route path="/about" element={<About navcontext="one" />} />
<Route path="/select1" element={<ScreenOne navcontext="one" />} />
<Route path="/select2" element={<ScreenTwo navcontext="two" />} />
<Route path="/select3" element={<ScreenThree navcontext="three" />} />
<Route path="/select4" element={<ScreenFour navcontext="four" />} />
<Route path="/restrict" element={<ScreenFive navcontext="restrict" />} />
</Routes>
<PersonList people={this.state.people} />
</div>
);
}
}
export default App;
我認為問題在於您在Nav
組件內的每個渲染周期都聲明了NavContext
上下文。 如果你需要使用 React 上下文,那么一定要在任何 React 組件之外聲明它。
我看不出在這里使用 React Context 有什么意義,盡管您可以有條件地在本地菜單menustatus
上呈現菜單項。
例子:
const Nav = (props) => {
const [menustatus, changeMenusStatus] = useState(null);
const changeContext = (input) => {
console.log(input);
changeMenusStatus(input);
};
useEffect(() => {
if (menustatus) {
console.log(menustatus);
} else {
console.log(`menustatus not set.`);
}
}, [menustatus]);
return (
<>
<h1>
<ReactLogo />
Base React App for Testing Development
</h1>
<nav>
<NavLink className="navitem" to="/">Home</NavLink>
<NavLink className="navitem" to="/select1">Selection 1</NavLink>
<NavLink className="navitem" to="/select2">Selection 2</NavLink>
{menustatus !== 'restrict' && (
<>
<NavLink className="navitem" to="/select3">Selection 3</NavLink>
<NavLink className="navitem" to="/select4">Selection 4</NavLink>
</>
)}
<NavLink className="navitem" to="/restrict" onClick={() => changeContext('restrict')}>RESTRICT</NavLink>
<NavLink className="navitem" to="/about">About</NavLink>
</nav>
</>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.