likes
comments
collection
share

React Function vs Class

作者站长头像
站长
· 阅读数 23

特性

在 React 中,我们有两种定义组件的方式:

  • 函数组件(Function Component)
  • 类组件(Class Component)

这两种类型的组件在 React 16.8 以前有很大差异,但是随着 Hooks 的发布,函数组件也拥有了和类组件几乎相同的功能。那么在 React 开发中,我们应该选择哪种组件类型呢?个人推荐优先选择函数组件,理由如下:

  1. 代码简洁性: 函数组件通常比类组件更简洁。由于函数组件不需要定义类和生命周期方法,它们的代码量更少,更易于理解和维护。

类组件

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }
  
  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
      </div>
    );
  }
}

函数组件

function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>You clicked {count} times</p>
    </div>
  );  
}

2. 性能: 函数组件通常比类组件具有更好的性能。由于函数组件没有内部状态和生命周期方法,React可以对它们进行更有效的优化。此外,函数组件还可以使用React的新特性,如React Hooks,来实现状态管理和副作用处理,进一步提高性能。

3. 可测试性: 函数组件通常比类组件更易于测试。由于函数组件是纯函数,它们的行为更可预测。可以更轻松地编写单元测试来验证函数组件的输出。

4. 上下文使用: 函数组件更适合使用React上下文(Context)。函数组件可以使用React的useContext钩子更轻松地访问上下文,而类组件需要使用this.context来访问上下文。

生命周期

类组件

  • constructor()
  • componentDidMount()
  • componentDidUpdate()
  • componentWillUnmount()
  • shouldComponentUpdate()
  • getDerivedStateFromProps()

函数组件:

  • useEffect()
  • useLayoutEffect()

实现对比

我们可以通过 React Hooks 在函数组件中实现类似的生命周期方法:

  • constructor() -> 没有直接对应,可以在函数组件中直接定义 state 和绑定方法
  • componentDidMount() -> useEffect(() => { ... }, [])  // 第2个参数为空数组
  • componentDidUpdate() -> useEffect(() => { ... })  // 无第二个参数,在每次更新时调用
  • componentWillUnmount() -> useEffect(() => { return () => { ... } })  // 返回一个清理函数
  • shouldComponentUpdate() -> React.memo()  // 包装组件以为其实现
  • shouldComponentUpdate getDerivedStateFromProps() -> 没有直接对应, 但是在大多数情况下可以用 useState() 代替如

类组件

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }
  
  componentDidMount() {
    console.log('componentDidMount');
  }
  
  componentDidUpdate() {
    console.log('componentDidUpdate');
  }
  
  componentWillUnmount() {
    console.log('componentWillUnmount');
  }
  
  shouldComponentUpdate() {
    console.log('shouldComponentUpdate');
    return true;
  }
  
  render() {
    return <div>{this.state.count}</div>   
  }
}

函数组件

function Example() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    console.log('componentDidMount');
  }, []);
  
  useEffect(() => {
    console.log('componentDidUpdate');
  });
  
  useEffect(() => {
    return () => {
      console.log('componentWillUnmount');  
    }
  }, []); 
  
  const MemoizedExample = React.memo(Example); // 实现 shouldComponentUpdate 
  
  return <div>{count}</div>   
} 

发展趋势

React Hook是自React 16.8版本引入的重要功能,它们提供了一种新的方式来处理组件的状态和副作用。以下是React Hook发展趋势的一些观察和预测:

1. 高度采用: 自React Hook引入以来,它们已经在React社区中广泛采用。许多开发者和团队已经转向使用函数组件和React Hook来构建他们的应用程序。这种趋势有助于推动React Hook的发展和改进,并为社区提供更多的工具和库。

2. 增加的生态系统: 随着React Hook的普及,开发者社区不断增加了与Hook相关的工具、库和插件。例如,有许多针对Hook的状态管理解决方案,如Redux Toolkit和Zustand。此外,还有一些用于处理常见副作用的自定义Hook库,如react-use和useSWR。这些工具和库丰富了React Hook的生态系统,并提供了更多的选择和功能。

3. React生态系统的演进: React Hook的引入改变了React应用程序的开发模式和架构思想。它们使得组件的状态逻辑更容易管理和测试,并推动了更模块化、可复用的代码实践。这种演进也在其他方面影响着React生态系统,例如改进了相关工具、测试库和开发者工具链的支持。

4. 不断改进和扩展: React团队一直在改进和扩展React Hook的功能。他们持续地收集反馈、修复问题和添加新的Hook。这表明React Hook将继续发展,以适应不断变化的需求,并提供更好的开发体验和性能。

5. 类组件的逐渐减少: 随着React Hook的成熟和普及,类组件在React应用程序中的使用逐渐减少。许多新的项目和代码库更倾向于使用函数组件和React Hook,因为它们提供了更简洁、可测试和性能优化的解决方案。

总结

React Hook在React开发中的地位和重要性不断增长。它们正在改变React应用程序的开发方式,并为开发者提供更好的工具和选择。随着时间的推移,我们可以预计React Hook将成为React开发的主流做法,并在React生态系统中发挥越来越重要的作用。