React Class组件和Function组件对比

1,017 阅读5分钟

一、class类组件

类组件,顾名思义,也就是通过ES6类的编写形式去编写组件,该类必须继承React.Component。 如果想要访问父组件传递过来的参数,可以通过this.props的方式去访问。 在组件中必须实现render方法,在return中返回react对象,如下:

class Welcome extends React.Component {
  constructor(props){
    super(props)
  }
  render() {
    return <h1>Hello, {this.props.name}</h1>
  }
}

二、函数式组件

函数式组件,顾名思义,就是通过函数编写的形式去实现一个React组件,定义组件方式简单。

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>
}

函数第一个参数为props用于接收父组件传递过来的参数

三、区别

主要分为以下几个方向:

  • 编写形式
  • 状态管理
  • 生命周期
  • 调用方式
  • 获取渲染的值

编写形式

两者最明显的区别在于编写形式的不同,同一种功能的实现可以分别对应类组件和函数组件的编写形式。

状态管理

在hooks出来之前,函数组件就是无状态组件,不能保管组件的状态,不像类组件中调用setState。hooks出现后,可以使用useState

const FunctionalComponent = () => {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <p>count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Click</button>
    <div>
  )
}

生命周期

在函数组件中,并不存在生命周期,这是因为这些生米周期的狗子都来自于继承的React.Component, 所以,在hooks出来之前,如果用到生命周期就只能使用类组件。 但是函数组件使用useEffect也能够替代生命周期的作用:

const FunctionalComponent = () => {
    React.useEffect(() => {
        console.log("Hello");
    }, []);
    return <h1>Hello, World</h1>;
};

如果在useEffect回调函数中return一个函数,则return函数会在组件卸载的时候执行,正如componentWillUnmount

const FunctionalComponent = () => {
 React.useEffect(() => {
   return () => {
     console.log("Bye");
   };
 }, []);
 return <h1>Bye, World</h1>;
};

调用方式

如果是一个函数组件,调用则是执行函数即可:

const SayHi = () => {
  return <p>Hello, React</p>
}
// React内部
const result = SayHi(props) // » <p>Hello, React</p>

如果是一个类组件,则需要讲组件进行实例化,然后调用对象的render方法:

class SayHi extends React.Component {
  render() {
    return <p>Hello, React</p>
  }
}
// React内部执行
const instance = new SayHi(props) // » SayHi {} 
const result = instance.render() // » <p>Hello, React</p >

获取渲染的值

在React 16.8版本引入React Hooks之前

function ProfilePage(props) {
  const showMessage = () => {
    alert('Followed ' + props.user);
  }

  const handleClick = () => {
    setTimeout(showMessage, 3000);
  }

  return (
    <button onClick={handleClick}>Follow</button>
  )
}
class ProfilePage extends React.Component {
  showMessage() {
    alert('Followed ' + this.props.user);
  }

  handleClick() {
    setTimeout(this.showMessage.bind(this), 3000);
  }

  render() {
    return <button onClick={this.handleClick.bind(this)}>Follow</button>
  }
}

两者看起来实现功能是一致的,但是在类组件中,输出this.props.user,Props在 React中是不可变的所以它永远不会改变,但是 this 总是可变的,以便您可以在 render 和生命周期函数中读取新版本 因此,如果我们的组件在请求运行时更新。this.props 将会改变。showMessage方法从“最新”的 props 中读取 user 而函数组件,本身就不存在this,props并不发生改变,因此同样是点击,alert的内容仍旧是之前的内容

四、优劣

class组件(Class Components):

特点:组件的生命周期方法(如:componentDidMounted、render等)以及状态(state)都是在类的实例中进行定义和管理的。 优势:

  1. 功能强大:类组件可以使用更多React特性,如生命周期方法和组件状态,使得处理复杂逻辑和状态管理更加方便。
  2. 更具可读性:类组件通过将相关的逻辑和状态进行分组,使得代码结构更加清晰和可读。利于项目维护。

劣势:

  1. 冗余和繁琐:类组件的编写需要更多的代码量,包括构造函数、方法定义等,导致代码结构相对复杂和冗余。
  2. 性能较低:类组件在一些性能相关的方面表现较差,因为它们会创建额外实例和处理更多的生命周期方法。
  3. 冗余原因:**类的构造函数:**类组件需要在构造函数中初始化状态和绑定方法,这使得定义一个简单的类组件需要额外的步骤和代码。**继承和方法绑定:**类组件需要使用类的继承来继承父类的成员方法,并通过绑定函数来确保方法在类实例中的正确执行上下文。这些额外的步骤和代码增加了方法定义的复杂性和冗余度。**this 关键字:**类组件中的方法需要使用 this 关键字来引用类的实例,以便访问类的属性和其他方法。这要求开发人员要注意正确使用和绑定 this,否则可能会导致错误。

函数式组件(Functional Components):

特点:它接收输入参数(props),并返回一个描述组件输出的 React 元素。 优势:

  1. 简洁易读:函数式组件相较于类组件更加简洁和易读,没有类的繁琐定义和生命周期方法,适合处理简单的场景。
  2. 性能优化:由于没有额外的实例和声明周期方法的开销,函数组件在一些方面新能表现更好,可以更高效地执行和渲染。

劣势:

  1. 功能受限:在过去,函数式组件的功能相对有限,无法使用状态和生命周期等特性。但是随着React的更新和引入Hooks,函数组件可以拥有更多的功能,如use State、useEffect等。

总结:

类组件使用于复杂的逻辑和状态管理,而函数组件更适合简单的场景和性能优化。