繁体   English   中英

我如何在 Class 组件中使用 useEffect() ?

[英]how could I use useEffect() in Class component?

我想用useEffect()代替componentWillMount() ,但我发现钩子不能在 class 组件中使用,所以我将代码更改为 Function 组件,但是整个组件会出现更多错误,所有代码都带有this.xxx 出现错误,我如何编辑以下代码以使其工作? 对于反应初学者来说并不容易。 请帮我。 下面的代码与componentWillMount()一起工作正常。

import React, { Component, useEffect } from 'react';
import { Link, withRouter } from 'react-router-dom';
import logo from '../../assets/images/logo.png';
import './index.less';
import { Menu } from 'antd';
import menuList from '../../config/menuConfig';

const { SubMenu } = Menu;
class LeftNav extends Component {
  getMenuNodes = menuList => {
    const path = this.props.location.pathname;
    return menuList.reduce((pre, item) => {
      if (!item.children) {
        pre.push(
          <Menu.Item key={item.key} icon={item.icon}>
            <Link to={item.key}>{item.title}</Link>
          </Menu.Item>,
        );
      } else {
        const cItem = item.children.find(cItem => cItem.key === path);
        if (cItem) {
          this.openKey = item.key;
        }
        pre.push(
          <SubMenu key={item.key} icon={item.icon} title={item.title}>
            {this.getMenuNodes(item.children)}
          </SubMenu>,
        );
      }
      return pre;
    }, []);
  };
  componentWillMount() {
    this.MenuNodes = this.getMenuNodes(menuList);
  }
  render () {
     //   useEffect(() => {
      //this.MenuNodes = this.getMenuNodes(menuList);
   // }, []);
    const path = this.props.location.pathname;
    console.log(path);
    const openKey = this.openKey;
    return (
      <div className="left-nav">
        <Link to="./" className="left-nav-header">
          <img src={logo} alt="" />
          <h1>Backend System</h1>
        </Link>
        <Menu
          selectedKeys={[path]}
          defaultOpenKeys={[openKey]}
          mode="inline"
          theme="dark"
        >
          {this.MenuNodes}
        </Menu>
      </div>
    );
  }
}
export default withRouter(LeftNav);

componentDidMount() 是您要使用的生命周期方法,它可以与您在功能组件中使用的 useEffect 进行比较。 componentWillMount() 已弃用,您不应使用它。

我尝试使用挂钩将您的 class 组件重构为功能组件。 最后我发现用useMemo hook代替useEffect hook更好。 useMemo用于记忆昂贵的计算,在本例中为 menuNodes 和 openKey 的计算。 useMemo将在依赖项发生变化时运行,在本例中为[menuList, path]

您还会注意到,我没有使用 withRouter Higher-Order-Component,而是将其替换为从“react-router-dom”调用useLocation挂钩。

让我知道这是否适合你,如果你有任何问题。

import React, { useMemo } from 'react';
import { Link, useLocation } from 'react-router-dom';
import logo from '../../assets/images/logo.png';
import './index.less';
import { Menu } from 'antd';
import menuList from '../../config/menuConfig';

const LeftNav = (props) => {
  const location = useLocation();
  const path = location.pathname;

  const { MenuNodes, openKey } = useMemo(() => {
    let openKey;

    const getMenuNodes = (menuList) => {
      return menuList.reduce((pre, item) => {
        if (!item.children) {
          pre.push(
            <Menu.Item key={item.key} icon={item.icon}>
              <Link to={item.key}>{item.title}</Link>
            </Menu.Item>
          );
        } else {
          const cItem = item.children.find((cItem) => cItem.key === path);
          if (cItem) {
            openKey = item.key;
          }
          pre.push(
            <Menu.SubMenu key={item.key} icon={item.icon} title={item.title}>
              {getMenuNodes(item.children)}
            </Menu.SubMenu>
          );
        }
        return pre;
      }, []);
    };

    const nodes = getMenuNodes(menuList);

    return { MenuNodes: nodes, openKey: openKey };
  }, [path]);

  return (
    <div className="left-nav">
      <Link to="./" className="left-nav-header">
        <img src={logo} alt="" />
        <h1>Backend System</h1>
      </Link>
      <Menu selectedKeys={[path]} defaultOpenKeys={[openKey]} mode="inline" theme="dark">
        {MenuNodes}
      </Menu>
    </div>
  );
};

export default LeftNav;

编辑

修复了 getMenuNodes 中的递归调用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM