反应路由器卸载功能组件
Posted
技术标签:
【中文标题】反应路由器卸载功能组件【英文标题】:react router unmount function component 【发布时间】:2019-10-02 15:22:40 【问题描述】:我正在使用 React Router 并且有两条路由渲染相同的组件:
<Switch>
<Route path="/aaa" component=Cmp />
<Route path="/bbb" component=Cmp />
</Switch>
这是 Cmp 实现:
class Cmp extends Component
componentWillUnmount()
console.log('******************* UNMOUNTED');
render()
return null;
正如我所料,在 /aaa
和 /bbb
之间导航不会卸载 Cmp。
我正在转向钩子,所以我重写了组件:
function Cmp()
useEffect(() =>
return () =>
console.log('******************* UNMOUNTED');
;
);
return null;
非常令人惊讶的是,在运行应用程序时,在 /aaa
和 /bbb
console.log 之间导航 Cmp 已卸载。
知道如何使用函数组件和钩子来防止不必要的卸载吗?
【问题讨论】:
看看这个,它可能会帮助reactjs.org/docs/… 不确定这是否有帮助,但看看React.memo 【参考方案1】:如果你想运行一个效果并且只清理一次(在挂载和卸载时),你可以传递一个空数组([])作为第二个参数。这告诉 React 你的效果不依赖于任何来自 props 或 state 的值,所以它永远不需要重新运行。这不是作为特殊情况处理的——它直接遵循依赖数组的工作方式。 ...read more
现在,每次重新渲染 Cmp
组件时都会调用您的效果。如果您只想在卸载时调用效果,则必须将带有空数组的第二个参数传递给 useEffect
:
useEffect(() =>
return () =>
console.log('******************* UNMOUNTED');
;
, []);
【讨论】:
【参考方案2】:这是人们使用useEffect
hook 时面临的一个非常普遍的问题。
useEffect
每次重新渲染组件时都会调用钩子。 hook 的第二个参数需要一个依赖数组,因此只有在依赖项发生变化时才会调用 hook。如果你给它提供空数组,钩子只会在挂载时运行,返回的函数会在卸载之前被调用。
提示:将此 ESLint 插件添加到您的项目中,以查找与钩子相关的问题。 https://www.npmjs.com/package/eslint-plugin-react-hooks
import React, useEffect from 'react';
import ReactDOM from 'react-dom';
import BrowserRouter, Route, Switch, Link from 'react-router-dom';
import './styles.css';
const DemoComponent = () =>
useEffect(() =>
return () =>
console.log('******************* UNMOUNTED');
;
, []);
return <div>Demo Component</div>;
;
const HomeComponent = () =>
return <div>Home Component</div>;
;
function App()
return (
<BrowserRouter>
<div>
<Link to="/">To Home</Link>
<br />
<Link to="/aaa">To AAA</Link>
<br />
<Link to="/bbb">To BBB</Link>
</div>
<Switch>
<Route path="/(aaa|bbb)" component=DemoComponent />
<Route path="/" component=HomeComponent />
</Switch>
</BrowserRouter>
);
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);
这是工作示例:https://codesandbox.io/s/9l393o7mlr
【讨论】:
【参考方案3】:结合 componentDidMount 和 componentWillUnmount
这意味着您可以在同一个 useEffect 函数调用中使用 componentDidMount 和 componentWillUnmount。显着减少管理这两个生命周期事件所需的代码量。这意味着您可以轻松地在功能组件中使用 componentDidMount 和 componentWillUnmount。像这样: 更多更新请React: UseEffect
import React, useEffect from 'react';
const ComponentExample => () =>
useEffect(() =>
// Anything in here is fired on component mount.
return () =>
// Anything in here is fired on component unmount.
, [])
【讨论】:
以上是关于反应路由器卸载功能组件的主要内容,如果未能解决你的问题,请参考以下文章