首页 > 解决方案 > 如何将异步 HOC 组件重写为 React Hooks?

问题描述

我正在为我的 React 应用程序使用模板,我遇到了一个组件,它不断地给我以下警告:

警告:componentWillMount 已重命名,不推荐使用。详见 https:...。

现在,我正在尝试将此组件重写为 React Hooks,以避免控制台中出现多个警告。

这是组件的样子:

import React, { Component } from 'react';
import Nprogress from 'nprogress';
import ReactPlaceholder from 'react-placeholder';
import 'nprogress/nprogress.css';
import 'react-placeholder/lib/reactPlaceholder.css';
import CircularProgress from '../components/CircularProgress/index';

export default function asyncComponent(importComponent) {
  class AsyncFunc extends Component {
    constructor(props) {
      super(props);
      this.state = {
        component: null,
      };
    }

    componentWillMount() {
      Nprogress.start();
    }

    componentWillUnmount() {
      this.mounted = false;
    }

    async componentDidMount() {
      this.mounted = true;
      const { default: Component } = await importComponent();
      Nprogress.done();
      if (this.mounted) {
        this.setState({
          component: <Component {...this.props} />,
        });
      }
    }

    render() {
      const Component = this.state.component
        || (
        <div
          className="loader-view"
          style={{ height: 'calc(100vh - 200px)' }}
        >
          <CircularProgress />
        </div>
        );
      return (
        <ReactPlaceholder type="text" rows={7} ready={Component !== null}>
          {Component}
        </ReactPlaceholder>
      );
    }
  }

  return AsyncFunc;
}

这是它的用法示例:

import React from 'react';
import { Route, Switch, withRouter } from 'react-router-dom';
import asyncComponent from '../util/asyncComponent';

const Routes = ({ match }) => (
  <Switch>
    <Route
      path={`${match.url}/main`}
      component={asyncComponent(() => import('./routes/MainPage/index'))}
    />
    {/* <Route component={asyncComponent(() => import("app/routes/extraPages/routes/404"))}/> */}
  </Switch>
);


export default withRouter(Routes);

我知道如何重写组件生命周期方法(componentDidMount,componentWillUnmount应该重写为useEffect),但我不明白props-asyncComponent获取importComponent作为道具的部分,但是我们在哪里获得propsAsyncFunc?以及如何将其重写为功能组件?

据我了解,asyncComponent是一个以更新的组件响应的高阶组件。

很抱歉没有为此示例提供沙箱。

标签: javascriptreactjs

解决方案


我无法测试这段代码,但我认为这是一个解决方案

import React, { useState, useEffect } from 'react';
import Nprogress from 'nprogress';
import ReactPlaceholder from 'react-placeholder';
import 'nprogress/nprogress.css';
import 'react-placeholder/lib/reactPlaceholder.css';
import CircularProgress from '../components/CircularProgress/index';

const asyncComponent = importComponent => {
  const [component, setComponent] = useState(null);

  Nprogress.start();

  useEffect(async () => {
    const { default: Component } = await importComponent();
    Nprogress.done();
    setComponent(<Component {...importComponent} />);
  }, []);

  return component ? (
    <ReactPlaceholder type="text" rows={7} ready>
      {component}
    </ReactPlaceholder>
  ) : (
    <div className="loader-view" style={{ height: 'calc(100vh - 200px)' }}>
      <CircularProgress />
    </div>
  );
};

export default asyncComponent;

我看不到需要使用状态mounted,因为你只在dismount to setState组件中使用它,但是如果2行之前你设置mounted为true,就不需要生成重新渲染,你可以去直接设置状态组件。

我希望这可以帮助你。

根据 reactjs.org 的说法,将来不会支持 componentWillMount。https://reactjs.org/docs/react-component.html#unsafe_componentwillmount

无需使用 componentWillMount。


推荐阅读