原因:1、函陣列件語法更短、更簡單,這使得它更容易開發、理解和測試;2、類元件過多的使用this讓整個邏輯看起來很混亂;3、hooks功能也只支援函陣列件;4、React團隊針對函陣列件做了更多的優化來避免非必要的檢查和記憶體漏失;5、函數式元件效能消耗小,因為函數式元件不需要建立範例,渲染的時候就執行一下,得到返回的react元素後就直接把中間量全部都銷燬。
前端(vue)入門到精通課程,老師線上輔導:聯絡老師
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API偵錯工具:
本教學操作環境:Windows7系統、react18版、Dell G3電腦。
當使用React框架開發的時候,有兩種方式建立元件,使用函數和使用類,目前函陣列件越來越流行。下面通過舉例的方式,分析函陣列件和類元件的不同,並總結一下使用函陣列件的原因(優勢)。
函陣列件和類元件處理JSX的方式不同,就像他們的名字,函陣列件是一個純Javascript函數,直接返回JSX;而類元件是一個Javascript類,通過擴充套件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,比如<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
屬性。
在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函數,即count
和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元素後就直接把中間量全部都銷燬。
【相關推薦:Redis視訊教學、】
以上就是react為什麼推薦函陣列件的詳細內容,更多請關注TW511.COM其它相關文章!