React useEffect 不会在路由更改时触发

Eri*_*dán 14 javascript reactjs react-router-v4 react-router-dom

我希望console.log('Refresh')每次路由更改时都会运行(从 Component1 切换到 Component2)。但它仅在第一次渲染时触发。为什么?

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(<BrowserRouter><App /></BrowserRouter>, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)

App.js

import React, { useEffect } from 'react';
import { Switch, Route } from 'react-router-dom';
import Nav from './Nav';
import Component1 from './Component1';
import Component2 from './Component2';

const App = () => {

  useEffect( () => console.log('Refresh'));

  return (
        [<Switch>
            <Route                            component = {Nav}/>
        </Switch>,
        <Switch>
            <Route exact path = '/component1' component = {Component1}/>
            <Route exact path = '/component2' component = {Component2}/>
        </Switch>]
  );
}

export default App;
Run Code Online (Sandbox Code Playgroud)

Nav.js

import React from 'react';
import { Link } from 'react-router-dom';

const  Nav = () => {
  return (
    <div>
        <Link to = '/component1'>Component 1</Link>
        <Link to = '/component2'>Component 2</Link>
    </div>
  );
}

export default Nav;
Run Code Online (Sandbox Code Playgroud)

Component1.js

import React from 'react';

const  Component1 = () => {

  return (
    <div>
        <p>Hi</p>
    </div>
  );
}

export default Component1;
Run Code Online (Sandbox Code Playgroud)

Component2.js

import React from 'react';

const  Component2 = () => {
  return (
    <div>
        <p>Bye</p>
    </div>
  );
}

export default Component2;
Run Code Online (Sandbox Code Playgroud)

Moh*_*ami 13

useEffect不会被触发,因为App组件没有重新渲染,没有在该组件(无状态或道具更新)改变。

如果你想让App组件在路由改变时重新渲染,你可以使用withRouterHOC 注入路由 props,如下所示:

import { Switch, Route, withRouter } from 'react-router-dom';

const App = () => {

  useEffect( () => console.log('Refresh'));

  return (...);
}

export default withRouter(App);
Run Code Online (Sandbox Code Playgroud)

示例:https : //codesandbox.io/s/youthful-pare-n8p1y

  • 这并没有解决我的问题。在我的情况下, useEffect 按预期工作,直到我导航到不同的路线,然后返回当前路线,然后 useEffect 不会触发,无论是否监听特定的状态变量,似乎都会发生。 (2认同)
  • 自 2021 年路由器 V6 起使用此 /sf/answers/4367245711/ (2认同)

小智 10

使用 key 属性,所以每次我们渲染新组件时(不同的键)

<Route path='/mypath/:username' exact render= {routeProps =><MyCompo {...routeProps} key={document.location.href} />} />
Run Code Online (Sandbox Code Playgroud)


onm*_*133 7

使用 useEffect 的第二个参数来有条件地应用效果。例如通过react-router-dom,你可以获得一些属性

const { schoolId, classId } = props

useEffect(() => {
   // fetch something here
}, [schoolId, classId)
Run Code Online (Sandbox Code Playgroud)

这里[schoolId, classId作为useEffect触发的唯一标识。


foa*_*ahi 7

使用钩子:

使用useLocationuseLayoutEffect获得更高的效率

   import { useLocation } from "react-router-dom";
//...
   const location = useLocation();
//...
   useLayoutEffect(() => {
    console.log("location",location) 
    
   }, [location])
Run Code Online (Sandbox Code Playgroud)