反应路由器卸载功能组件

时间:2019-05-15 13:03:10

标签: reactjs react-router react-router-v4 react-hooks

我正在使用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。
知道如何使用功能组件和挂钩防止不必要的卸载吗?

3 个答案:

答案 0 :(得分:2)

这是人们使用user.getIDTokenResult(completion: { (result, error) in guard let model = result?.claims?["model"] as? NSNumber else { // Something } if model.boolValue { // Show something else } else { // Something else again } }) 钩子面临的一个非常普遍的问题。

每次重新渲染组件时都会调用

useEffect挂钩。 hook的第二个参数需要一个依赖项数组,因此只有在依赖项已更改的情况下才会调用hook。而且,如果您为其提供空数组,则hook将仅在mount上运行,并且返回的函数将在unmount之前被调用。

提示:将此ESLint插件添加到您的项目中,以查找此类与挂钩相关的问题。 https://www.npmjs.com/package/eslint-plugin-react-hooks

useEffect

这是工作示例:https://codesandbox.io/s/9l393o7mlr

答案 1 :(得分:1)

  

如果要运行效果并仅将其清理一次(在挂载和卸载时),则可以将空数组([])作为第二个参数传递。这告诉React,您的效果不依赖于道具或状态的任何值,因此它不需要重新运行。这不是特殊情况,它直接取决于依赖项数组始终如何工作。 ...read more

现在,每次Cmp组件的重新渲染都会调用您的效果。如果只想在卸载时调用效果,则必须将带有空数组的第二个参数传递给useEffect

useEffect(() => {
    return () => {
        console.log('******************* UNMOUNTED');
    };
}, []);

答案 2 :(得分:0)

结合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.
            }
        }, [])
    }