最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 如何在class组件中使用hooks

    正文概述 掘金(ScarlettLL)   2020-12-07   617

    问题

    前不久在开发中遇到一个问题,在一个基于class component的react项目,想要使用像hooks里的useEffect这样的函数,来监听某些props的变化,每当这些props变化时,都要执行一遍指定的函数。
    如果是在一个使用hooks的组件里,想要实现这样的效果直接使用useEffect即可,但是问题就在于目前的这个组件是用class写的,而且组件也很庞大复杂,如果想要用hooks重写,一是时间不允许,二是测试不允许,重写后必须得重新测试(测试同学OS:已经测试过的功能你怎么又让我重测一遍,(╯`□′)╯~ ╧╧,不干!)。
    那么摆在面前的问题来了:如何在class组件中使用hooks函数?
    首先第一步肯定是先翻看一下官方文档,看一下有没有标准的解决方案,但是很不幸的是: 如何在class组件中使用hooks 这就意味着,Hooks不是一个使项目更简洁的小功能,而是React一个完全不同于class组件的全新的核心概念。
    既然官方已经明确说了,class组件里hooks函数是不生效的,那么是不是我们的问题就没有解了呢?当然不是,在JavaScript的世界里,一切皆有解决办法。

    解决办法

    以一个简单的useScreenWidthhook函数威力,它的目的是获取全屏的宽度,并且去监听浏览器窗口的变化,更新宽度:

    import { useEffect, useState } from 'react';
    
    export function useScreenWidth(): number {
      const [width, setWidth] = useState(window.innerWidth);
    
      useEffect(() => {
        const handler = (event: any) => {
          setWidth(event.target.innerWidth);
        };
        // 监听浏览器窗口变化
        window.addEventListener('resize', handler);
        // 组件unmount时要解除监听
        return () => {
          window.removeEventListener('resize', handler);
        };
      }, []);
    
      return width;
    }
    

    useState

    返回两个值:一个是state状态值,另一个是它的setter函数。

    useEffect

    有两个参数:第一个是要执行的函数,第二个是要监听的变量组成的数组。如果监听数组中某一个值发生了变化,那么第一个参数(要执行的函数)就会在下一轮渲染时执行。 第二个参数有三种情况:

    • 没有任何参数:useEffect在每一次重渲染都会执行
    • 空数组[]useEffect只会在第一次渲染时执行,因为空数组不会有变化
    • [arg1, arg2, ...]:数组中任意值发生了变化,useEffect在下一次渲染都会执行

    方法1:将Hook包装成HOC

    HOC是React中复用组件的高级用法,它的本质是一个函数,它的输入参数是一个组件,返回相同的组件以及一些额外的props。在我们的例子里,可以让hook函数作为props传递到目标组件中:

    import React from 'react';
    import { useScreenWidth } from '../hooks/useScreenWidth';
    
    export const withHooksHOC = (Component: any) => {
      return (props: any) => {
        const screenWidth = useScreenWidth();
    
        return <Component width={screenWidth} {...props} />;
      };
    };
    

    最后一步就是将我们的目标组件用上述的withHooksHOC包装起来,那么我们就可以将width传递给了目标组件:

    import React from 'react';
    import { withHooksHOC } from './withHooksHOC';
    
    interface IHooksHOCProps {
      width: number;
    }
    
    class HooksHOC extends React.Component<IHooksHOCProps> {
      render() {
        return <p>width: {this.props.width}</p>;
      }
    }
    
    export default withHooksHOC(HooksHOC);
    

    方法2:将Hook包装成函数组件

    另外一种方法就是将hook变成函数组件,它接收一个参数为widthchildren函数,然后将width作为render prop传递:

    import { FunctionComponent } from 'react';
    import { useScreenWidth } from '../hooks/useScreenWidth';
    
    type ScreenWidthChildren = (screenWidth: number) => React.ReactNode;
    
    interface IScreenWidthProps {
      children: ScreenWidthChildren;
    }
    
    export const ScreenWidth: FunctionComponent<IScreenWidthProps> = ({
      children,
    }) => {
      const screenWidth: number = useScreenWidth();
    
      return children(screenWidth);
    };
    

    使用:

    import React from 'react';
    import { ScreenWidth } from './ScreenWidth';
    
    export class HooksRenderProps extends React.Component {
      render() {
        return (
          <ScreenWidth>
            {(width) => <p style={{ fontSize: '48px' }}>width: {width}</p>}
          </ScreenWidth>
        );
      }
    }
    

    起源地下载网 » 如何在class组件中使用hooks

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元