> 웹 프론트엔드 > 프런트엔드 Q&A > React가 함수 구성요소를 추천하는 이유

React가 함수 구성요소를 추천하는 이유

青灯夜游
풀어 주다: 2022-12-05 18:11:38
원래의
2440명이 탐색했습니다.

이유: 1. 함수 구성 요소 구문이 더 짧고 단순하여 개발, 이해 및 테스트가 더 쉽습니다. 2. 클래스 구성 요소에서 이를 과도하게 사용하면 전체 논리가 혼란스러워 보입니다. 3. 후크 기능은 함수 구성 요소만 지원합니다. 4. React 팀은 불필요한 검사와 메모리 누수를 피하기 위해 함수 구성 요소에 대해 더 많은 최적화를 수행했습니다. 5. 기능 구성 요소는 반환된 반응 요소를 얻은 후 인스턴스를 생성할 필요가 없고 렌더링 시 실행되기 때문에 성능 소모가 적습니다. , 모든 중간 금액을 직접 파기합니다.

React가 함수 구성요소를 추천하는 이유

이 튜토리얼의 운영 환경: Windows 7 시스템, React18 버전, Dell G3 컴퓨터.

React 프레임워크를 사용하여 개발할 때 컴포넌트를 만드는 방법에는 함수를 사용하는 방법과 클래스를 사용하는 방법이 있습니다. 현재 함수 컴포넌트가 점점 더 대중화되고 있습니다. 다음은 예제를 사용하여 기능 컴포넌트와 클래스 컴포넌트의 차이점을 분석하고, 기능 컴포넌트를 사용하는 이유(장점)를 요약합니다.

JSX 렌더링 방법


함수 구성 요소와 클래스 구성 요소는 이름처럼 JSX를 처리하는 방식이 다릅니다. 함수 구성 요소는 JSX를 직접 반환하는 순수 Javascript 함수인 반면, 클래스 구성 요소는 를 확장하는 Javascript 클래스입니다. React.Component를 작성하고 JSX를 반환하는 render 메서드를 구현합니다. 다음은 예시입니다.
React.Component,并实现render方法,render方法中返回JSX。下面举例说明:

import React from "react";
 const FunctionalComponent = () => {
 return <h1>Hello, world</h1>;
 };
로그인 후 복사

上面通过ES6箭头函数的形式定义了一个函数组件,函数体内直接返回JSX。如果你对箭头函数不熟悉,也可以写成下面这种形式:

import React from "react";
function FunctionalComponent() {
 return <h1>Hello, world</h1>;
 }
로그인 후 복사

两种写法是一样的。

然后,来看看如何定义类组件,首先我们需要扩展React.Component,然后在render方法中返回JSX,具体看下面的代码片段:

import React, { Component } from "react";
class ClassComponent extends Component {
 render() {
   return <h1>Hello, world</h1>;
 }}
로그인 후 복사

上面使用了ES6的解构赋值语法来导入模块,如果你对解构赋值语法不熟悉,也可以写成下面这种形式,会看上去更简洁一些:

import React from "react";
class ClassComponent extends React.Component {
 render() {
   return <h1>Hello, world</h1>;
 }
 }
로그인 후 복사

传递props


当需要向一个组件传递数据的时候,我们使用props,比如<FunctionalComponent name="Shiori" />,name就是Component的一个props属性,这里可以有更多属性。FunctionalComponent组件的函数形式的定义如下:

const FunctionalComponent = ({ name }) => {
 return <h1>Hello, {name}</h1>;
 };
로그인 후 복사

或者不使用解构赋值

const FunctionalComponent = (props) => {
 return <h1>Hello, {props.name}</h1>;
 };
로그인 후 복사

这种方式,你需要使用props.name来获取name属性。

然后,我们来看看类组件如何使用props,

class ClassComponent extends React.Component {
  render() {
    const { name } = this.props;
    return <h1>Hello, { name }</h1>;
 }}
로그인 후 복사

在类组件中,你需要使用this来获取props,然后可以使用解构赋值获取name属性。

处理state


在React项目中,我们不可避免的要处理状态变量。类组件直到最近才支持处理状态,然而,从React从16.8版本开始,函数组件支持钩子方法useState,这样我们可以很方便的在函数组件中使用状态变量。下面通过一个counter计数器实例来说明它们的不同。

在函数组件中处理状态变量

const FunctionalComponent = () => {
 const [count, setCount] = React.useState(0);
 return (
   <div>
     <p>count: {count}</p>
     <button onClick={() => setCount(count + 1)}>Click</button>
   </div>
 );};
로그인 후 복사

这里使用useState钩子,它接收一个初始的state作为参数。在本例中,计数器从0开始,所以我们给count一个初始值0。

state的初始值支持各种数据类型,包括null,string或者object对象,只要是javascript允许的都可以。在=号的左边,我们使用解构赋值的形式来接受useState的返回值,包括当前的状态变量和更新该变量的setter函数,即countsetCount

class ClassComponent extends React.Component {
 constructor(props) {
   super(props);
   this.state = {
     count: 0
   };
 }
 render() {
   return (
     <div>
       <p>count: {this.state.count} times</p>
       <button onClick={() => this.setState({ count: this.state.count + 1 })}>
         Click
       </button>
     </div>
   );
 }}
로그인 후 복사

위에서는 ES6 화살표 함수 형식으로 함수 구성요소를 정의하고, 함수 본문은 JSX를 직접 반환합니다. 화살표 기능에 익숙하지 않다면 다음과 같은 형식으로 작성하셔도 됩니다.

onClick={() =>
  this.setState((state) => {
    return { count: state.count + 1 };
  })}
로그인 후 복사
로그인 후 복사

두 가지 작성 방법은 동일합니다.

그럼 클래스 컴포넌트를 정의하는 방법을 살펴보겠습니다. 먼저 React.Component를 확장한 다음 render 메서드에서 JSX를 반환해야 합니다. 자세한 내용은 다음 코드 조각을 참조하세요.

🎜
const FunctionalComponent = () => {
 React.useEffect(() => {
   console.log("Hello");
 }, []);
 return <h1>Hello, World</h1>;};
로그인 후 복사
로그인 후 복사
🎜

위에서는 ES6의 구조 분해 할당 구문을 사용하여 모듈을 가져옵니다. 구조 분해 할당 구문에 익숙하지 않은 경우 다음을 수행할 수도 있습니다. 다음 형식으로 작성하면 더 간결해 보입니다. :🎜🎜

class ClassComponent extends React.Component {
 componentDidMount() {
   console.log("Hello");
 }
 render() {
   return <h1>Hello, World</h1>;
 }}
로그인 후 복사
로그인 후 복사
🎜🎜🎜Passing props🎜🎜🎜

데이터를 컴포넌트에 전달해야 할 때 다음과 같은 props를 사용합니다. <FunctionalComponent name="Shiori" /&gt ;와 같이 name은 Component의 props 속성이므로 여기에 더 많은 속성이 있을 수 있습니다. FunctionalComponent 구성 요소의 기능적 형태는 다음과 같이 정의됩니다.
🎜🎜

const FunctionalComponent = () => {
 React.useEffect(() => {
   return () => {
     console.log("Bye");
   };
 }, []);
 return <h1>Bye, World</h1>;};🎜<p data-pid="e-i4xpLf">또는 구조 분해 할당을 사용하지 마세요🎜🎜</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">class ClassComponent extends React.Component {
 componentWillUnmount() {
   console.log("Bye");
 }
 render() {
   return <h1>Bye, World</h1>;
 }}
로그인 후 복사
로그인 후 복사
🎜

이러한 방법을 사용하려면 props.name을 사용하여 name 속성을 가져와야 합니다. 🎜

그럼 클래스 컴포넌트에서 props를 어떻게 사용하는지 살펴보겠습니다. 🎜🎜rrreee🎜

클래스 컴포넌트에서는 이것을 사용해야 합니다. > 소품을 가져온 다음 구조 분해 할당을 사용하여 name 속성을 ​​가져올 수 있습니다. 🎜🎜🎜상태 처리🎜🎜🎜

React 프로젝트에서는 필연적으로 상태 변수를 처리해야 합니다. 클래스 컴포넌트는 최근까지 상태 처리를 지원하지 않았습니다. 그러나 React 버전 16.8부터 함수 컴포넌트에서는 후크 메소드 useState를 지원하므로 함수 컴포넌트에서 상태 변수를 쉽게 사용할 수 있습니다. 다음에서는 카운터 카운터 예를 사용하여 차이점을 설명합니다.
🎜🎜🎜함수 구성요소의 상태 변수 처리🎜🎜🎜rrreee🎜

여기에서는 초기 상태를 매개변수로 받는 useState 후크가 사용됩니다. . 이 예에서는 카운터가 0부터 시작하므로 count에 초기 값 0을 제공합니다. 🎜

상태의 초기값은 자바스크립트에서 허용하는 한 null, 문자열, 객체 객체 등 다양한 데이터 유형을 지원합니다. = 숫자의 왼쪽에서는 현재 상태 변수와 변수를 업데이트하는 setter 함수, 즉 count를 포함하여 useState의 반환 값을 허용하기 위해 구조 분해 할당 형식을 사용합니다. 및 setCount

. 🎜🎜🎜클래스 구성 요소의 상태 변수 처리🎜🎜🎜rrreee🎜

与函数组件大同小异,首先我们要理解React.Component的构造函数constructor,react的官方文档对constructor的定义如下:

“The constructor for a React component is called before it is mounted. When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. Otherwise, this.props will be undefined in the constructor, which can lead to bugs.”

翻译一下,

React组件的constructor方法会在组件完全加载完成之前调用。在constructor方法中,你需要在第一行调用super(props),否则会报this.props是undefined的错误。

如果在类组件中,你没有实现constructor方法并调用super(props),那么所有的状态变量都将是undefined。所以,别忘记先定义constructor方法,在constructor方法中,我们需要给this.state一个初始值,像上面的代码那样。然后我们可以在JSX中使用this.state.count来获取count的值,setter的使用也是类似的。

这里先定义一个onClick方法,后面会用到,

onClick={() =>
  this.setState((state) => {
    return { count: state.count + 1 };
  })}
로그인 후 복사
로그인 후 복사

这里注意setState()方法接收的是个箭头函数,而箭头函数的参数是state和props,props是可选的,这里没用到就没写。

生命周期函数


React的组件在它整个的渲染的过程中,有它的生命周期。如果你之前一直使用类组件,刚刚接触函数组件,你可能会疑惑,为什么在函数组件中没有componentDidMount()这类的生命周期方法?但是别急,有其他的钩子函数可以使用。

加载阶段

类组件的生命周期函数componentDidMount会在首次渲染完成之后调用。首次渲染完成之前会调用componentWillMount ,但是这个方法在新版本的React中不推荐使用了。

在函数组件中,我们使用useEffect钩子函数来处理生命周期内的事件,像下面这样,

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

useEffect有两个参数,第一个是箭头函数,第二个是[][]里面是变化的state(s)。什么意思呢?就是[]中的状态变化了,箭头函数会被调用。如果像现在这样写个[],那箭头函数只会在组件第一次渲染之后调用一次,其功能类似下面类组件的componentDidMount

class ClassComponent extends React.Component {
 componentDidMount() {
   console.log("Hello");
 }
 render() {
   return <h1>Hello, World</h1>;
 }}
로그인 후 복사
로그인 후 복사

卸载阶段

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

这里注意return的也是一个箭头函数,这个函数就是在卸载阶段执行的。当你需要执行一些卸载操作,可以放在这里,比如你可以把clearInterval放在这里,避免内存泄漏。使用useEffect钩子函数的最大好处就是可以把加载函数和卸载函数放在一个同一个地方。这里对比一下类组件的写法:

class ClassComponent extends React.Component {
 componentWillUnmount() {
   console.log("Bye");
 }
 render() {
   return <h1>Bye, World</h1>;
 }}
로그인 후 복사

总结


函数组件和类组件各有优缺点,但函数组件相比类组件的优势:

  • 函数组件语法更短、更简单,这使得它更容易开发、理解和测试;而类组件也会因大量使用 this而让人感到困惑

  • 类组件过多的使用this让整个逻辑看起来很混乱;

  • React团队主推的React hooks功能也只支持函数组件;

  • React团队针对函数组件做了更多的优化来避免非必要的检查和内存泄漏;

    注:React团队也在努力将hooks功能引入类组件,所以没必要将现有的类组件都改写成函数组件;

  • 类组件的性能消耗比较大,因为类组件需要创建类组件的实例,而且不能销毁。

    函数式组件性能消耗小,因为函数式组件不需要创建实例,渲染的时候就执行一下,得到返回的react元素后就直接把中间量全部都销毁。

【相关推荐:Redis视频教程编程入门

위 내용은 React가 함수 구성요소를 추천하는 이유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 추천
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿