React:函数组件(Functional Components)vs. 类组件(Class Components)

文章讨论了React中类组件与函数组件的封装方式转变,重点在于状态管理和生命周期管理。Hooks的引入使函数组件具备状态管理能力,虽然函数组件使用更简洁,但生命周期管理需借助useEffect。作者倾向于推荐使用函数组件,符合React官方趋势。
摘要由CSDN通过智能技术生成

组件封装是React的核心思想,ReactJS有两种封装组件的方式:

  • 以类(class)的方式封装组件
  • 以函数(function)的方式封装组件

旧的React官方文档中,是使用类组件的:

class HelloMessage extends React.Component {
  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

但到了新官方文档,已经改成使用函数组件了:

function HelloMessage({name}) {
  return(
      <div>Hello {name}</div>
  )
}

那么,为什么会有两种组件封装方式呢?两者又有什么不同,我们应该如何选择?

React为什么会有两种组件封装方式?

从官方文档的变化就能看出,两种封装方式是有先后关系的,早期主要采用类的方式封装组件。主要原因是组件中的状态管理问题。
有时在组件中需要维护变量,比如统计某个按钮的点击次数,这种在内部需要维护变量的组件称为带状态组件(stateful components)。

在2019年2月6号之前,带状态组件只能以类的方式封装。早期官方文档给出了带状态组件的实例:

class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = { seconds: 0 };
  }

  tick() {
    this.setState(state => ({
      seconds: state.seconds + 1
    }));
  }

  componentDidMount() {
    this.interval = setInterval(() => this.tick(), 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return (
      <div>
        Seconds: {this.state.seconds}
      </div>
    );
  }
}

root.render(<Timer />);

这也是早期React以类组件为主的原因,毕竟大部分组件都是带状态的。

直到2019年2月,情况发生了改变。React 16.8.0发布,该版本引入了Hooks的概念

Hooks — a way to use state and other React features without writing a class.

有了Hooks,在函数组件中也可以实现状态管理了,使用方法如下:

import { useState } from 'react';

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }
  return (<button onClick={handleClick}>{count}</button>);
}

并且Hooks只能在函数组件中使用

两种封装方式的优缺点

有了hooks,两种组件封装方式好像又站在了同一起跑线上。那么在其他方面两者有什么优缺点呢?

从官方文档改为使用函数组件可以推测,函数组件成了新的趋势,那么是不是函数组件有更多优点呢

个人觉得,函数组件的优点是使用起来更加简单,主要体现在,与类组件相比:

  • 函数组件不需要构造函数,类组件如果需要管理状态,就必须有构造函数
  • 函数组件不需要render()函数,类组件必须通过render()函数返回JSX

当然,函数组件也有它的问题,组件生命周期的管理就是问题之一。

类组件可以利用生命周期函数,在不同的生命周期执行不同代码。比如像上面代码中,在组件被挂载时,也就是componentDidMount()时创建计时器,并在组件被移除,也就是componentWillUnmount()删除计时器。

生命周期的问题,在函数组件中也是可以解决的,官方文档中就给出了方式,就是利用useEffect

应该选择哪种组件封装方式?

Hooks出现以后,函数组件逐渐受到追捧,相应的工具也越来越完善。
useRefuseNavigateuseLocation等官方hook的出现,以及Redux等常用的项目纷纷增加了对hooks的支持,这也使得函数组件使用起来越来越方便,从而形成良性循环,函数组件使用越来越广泛。

所以总的来说,更建议采用函数的方式封装组件,这应该也是官方鼓励的趋势

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值