我希望每次路由更改时(从 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;
useEffect
未触发,因为App
组件未重新渲染,该组件中没有任何更改(没有状态或道具更新)。
如果您希望
App
组件在路线更改时重新渲染,您可以使用 withRouter
HOC 注入路线道具,如下所示:
import { Switch, Route, withRouter } from 'react-router-dom';
const App = () => {
useEffect( () => console.log('Refresh'));
return (...);
}
export default withRouter(App);
使用 key 属性,这样每次我们渲染新组件(不同的键)
<Route path='/mypath/:username' exact render= {routeProps =><MyCompo {...routeProps} key={document.location.href} />} />
使用 useEffect 的第二个参数来有条件地应用效果。例如通过react-router-dom,你可以获得一些属性
const { schoolId, classId } = props
useEffect(() => {
// fetch something here
}, [schoolId, classId)
这里
[schoolId, classId
作为useEffect触发的唯一标识。
使用钩子:
使用
useLocation
和 useLayoutEffect
获得 更高效率:
import { useLocation } from "react-router-dom";
//...
const location = useLocation();
//...
useLayoutEffect(() => {
console.log("location",location)
}, [location])
如果您正在使用路线中的身份
: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