簡體   English   中英

React useEffect 在第二次點擊時呈現變化?

[英]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>
    </>
  );
}

編輯 react-useeffect-renders-change-on-2nd-click

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM