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

问题描述 投票:0回答:5

我希望每次路由更改时(从 Component1 切换到 Component2),

console.log('Refresh')
都会运行。但它仅在第一次渲染时触发。为什么?

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'));

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;

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;

Component1.js

import React from 'react';

const  Component1 = () => {

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

export default Component1;

Component2.js

import React from 'react';

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

export default Component2;
javascript reactjs react-router-v4 react-router-dom
5个回答
22
投票

useEffect
未触发,因为
App
组件未重新渲染,该组件中没有任何更改(没有状态或道具更新)。

如果您希望

App
组件在路线更改时重新渲染,您可以使用
withRouter
HOC 注入路线道具,如下所示:

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

const App = () => {

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

  return (...);
}

export default withRouter(App);

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


18
投票

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

<Route path='/mypath/:username' exact render= {routeProps =><MyCompo {...routeProps} key={document.location.href} />} />

7
投票

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

const { schoolId, classId } = props

useEffect(() => {
   // fetch something here
}, [schoolId, classId)

这里

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


6
投票

使用钩子:

使用

useLocation
useLayoutEffect
获得 更高效率:

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

0
投票

如果您正在使用路线中的身份

:id
,如

 import react from 'react';
 import { Route,Routes } from 'react-router-dom';
 import Properties from './pages/properties';


 function App() {
   return (
           <div>
     <Routes>
         <Route path="/" element={<Home/>} >
            <Route path="properties/:id" element={<Properties/>}/> 
         </Route> 
    </Routes>
 </div>
 );
 }

并且您希望属性组件基于标识

re-render
 
:id

你可以在属性组件中简单地这样写

 import React,{useEffect} from "react";
 import {  useParams} from "react-router-dom";

 export default Properties(){
   useEffect(()=>{

   return (){...}
  },[useParams.id])


 return <div> .....</div>
 }

它始终会为搜索参数的每次更改提供

re-render
属性组件
:id

© www.soinside.com 2019 - 2024. All rights reserved.