Sebab: 1. Sintaks komponen fungsi lebih pendek dan ringkas, yang menjadikannya lebih mudah untuk dibangunkan, difahami dan diuji 2. Penggunaan yang berlebihan dalam komponen kelas menjadikan keseluruhan logik kelihatan mengelirukan; hanya menyokong komponen fungsi; 4. Pasukan React telah membuat lebih banyak pengoptimuman untuk komponen fungsi untuk mengelakkan semakan yang tidak perlu dan kebocoran memori 5. Komponen berfungsi mempunyai penggunaan prestasi yang rendah kerana komponen berfungsi tidak perlu membuat contoh dan membuat Hanya laksanakan apabila anda mendapat; unsur tindak balas yang dikembalikan dan memusnahkan semua jumlah perantaraan secara langsung.
Persekitaran pengendalian tutorial ini: sistem Windows 7, versi react18, komputer Dell G3.
Apabila membangun menggunakan rangka kerja React, terdapat dua cara untuk mencipta komponen, menggunakan fungsi dan menggunakan kelas Pada masa ini, komponen fungsi menjadi semakin popular. Berikut menggunakan contoh untuk menganalisis perbezaan antara komponen berfungsi dan komponen kelas, dan meringkaskan sebab (kelebihan) untuk menggunakan komponen berfungsi.
Komponen fungsi dan komponen kelas memproses JSX secara berbeza Sama seperti namanya, komponen fungsi ialah fungsi Javascript tulen, Mengembalikan JSX secara langsung ; komponen kelas ialah kelas Javascript yang memanjangkan React.Component
dan melaksanakan kaedah render, yang mengembalikan JSX. Berikut ialah contoh:
import React from "react"; const FunctionalComponent = () => { return <h1>Hello, world</h1>; };
Di atas mentakrifkan komponen fungsi dalam bentuk fungsi anak panah ES6, dan badan fungsi mengembalikan JSX secara langsung. Jika anda tidak biasa dengan fungsi anak panah, anda juga boleh menulisnya dalam bentuk berikut:
import React from "react"; function FunctionalComponent() { return <h1>Hello, world</h1>; }
Dua kaedah penulisan adalah sama.
Kemudian, mari kita lihat cara mentakrifkan komponen kelas Mula-mula kita perlu memanjangkan React.Component
dan kemudian mengembalikan JSX dalam kaedah pemaparan untuk butiran, lihat coretan kod berikut:
import React, { Component } from "react"; class ClassComponent extends Component { render() { return <h1>Hello, world</h1>; }}
Di atas menggunakan sintaks tugasan penstrukturan ES6 untuk mengimport modul Jika anda tidak biasa dengan sintaks tugasan penstrukturan, anda juga boleh menulisnya dalam bentuk berikut, yang akan kelihatan lebih ringkas. :
import React from "react"; class ClassComponent extends React.Component { render() { return <h1>Hello, world</h1>; } }
Apabila kita perlu menghantar data kepada komponen, kita menggunakan prop, seperti <FunctionalComponent name="Shiori" />
, nama ialah atribut prop bagi Komponen, di sini Terdapat lebih banyak atribut. Bentuk fungsi FunctionalComponent ditakrifkan seperti berikut:
const FunctionalComponent = ({ name }) => { return <h1>Hello, {name}</h1>; };
atau tidak menggunakan tugasan memusnahkan
const FunctionalComponent = (props) => { return <h1>Hello, {props.name}</h1>; };
, anda perlu menggunakan props.name
untuk mendapatkan atribut nama.
Kemudian, mari kita lihat cara komponen kelas menggunakan prop,
class ClassComponent extends React.Component { render() { const { name } = this.props; return <h1>Hello, { name }</h1>; }}
Dalam komponen kelas, anda perlu menggunakan this
untuk mendapatkan prop, dan maka anda boleh Gunakan tugasan pemusnah untuk mendapatkan atribut name
.
Dalam projek React, sudah semestinya kita perlu berurusan dengan pembolehubah keadaan. Komponen kelas tidak menyokong keadaan pengendalian sehingga baru-baru ini, namun, bermula dari React versi 16.8, komponen fungsi menyokong kaedah cangkuk useState
, supaya kita boleh menggunakan pembolehubah keadaan dengan mudah dalam komponen fungsi. Berikut menggunakan contoh pembilang untuk menggambarkan perbezaan mereka.
const FunctionalComponent = () => { const [count, setCount] = React.useState(0); return ( <div> <p>count: {count}</p> <button onClick={() => setCount(count + 1)}>Click</button> </div> );};
Di sini kami menggunakan cangkuk useState
, yang menerima keadaan awal sebagai parameter. Dalam contoh ini, kaunter bermula pada 0, jadi kami memberikan kiraan nilai awal 0.
Nilai awal keadaan menyokong pelbagai jenis data, termasuk objek null, rentetan atau objek, selagi javascript membenarkannya. Di sebelah kiri tanda =
, kami menggunakan bentuk tugasan memusnahkan untuk menerima nilai pulangan useState, termasuk pembolehubah keadaan semasa dan fungsi penetap yang mengemas kini pembolehubah, iaitu count
dan setCount
.
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> ); }}
与函数组件大同小异,首先我们要理解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团队也在努力将hooks功能引入类组件,所以没必要将现有的类组件都改写成函数组件;
类组件的性能消耗比较大,因为类组件需要创建类组件的实例,而且不能销毁。
函数式组件性能消耗小,因为函数式组件不需要创建实例,渲染的时候就执行一下,得到返回的react元素后就直接把中间量全部都销毁。
Atas ialah kandungan terperinci Mengapa bertindak balas mengesyorkan komponen fungsi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!