
一、類組件
類組件,顧名思義,也就是通過使用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組件,是React中定義組件最簡單的方式
function Welcome(props) { return <h1>Hello, {props.name}</h1>; }
函數第一個參數為props用於接收父組件傳遞過來的參數
三、區別
針對兩種React組件,其區別主要分成以下幾大方向:
-
編寫形式
-
狀態管理
-
生命周期
-
調用方式
-
獲取渲染的值
編寫形式
兩者最明顯的區別在於編寫形式的不同,同一種功能的實現可以分別對應類組件和函數組件的編寫形式
函數組件:
function Welcome(props) { return <h1>Hello, {props.name}</h1>; }
類組件:
class Welcome extends React.Component { constructor(props) { super(props) } render() { return <h1>Hello, {this.props.name}</h1> } }
狀態管理
在hooks出來之前,函數組件就是無狀態組件,不能保管組件的狀態,不像類組件中調用setState
如果想要管理state狀態,可以使用useState,如下:
const FunctionalComponent = () => { const [count, setCount] = React.useState(0); return ( <div> <p>count: {count}</p> <button onClick={() => setCount(count + 1)}>Click</button> </div> ); };
在使用hooks情況下,一般如果函數組件調用state,則需要創建一個類組件或者state提升到你的父組件中,然后通過props對象傳遞到子組件
生命周期
在函數組件中,並不存在生命周期,這是因為這些生命周期鈎子都來自於繼承的React.Component
所以,如果用到生命周期,就只能使用類組件
但是函數組件使用useEffect也能夠完成替代生命周期的作用,這里給出一個簡單的例子:
const FunctionalComponent = () => { useEffect(() => { console.log("Hello"); }, []); return <h1>Hello, World</h1>; };
上述簡單的例子對應類組件中的componentDidMount生命周期
如果在useEffect回調函數中return一個函數,則return函數會在組件卸載的時候執行,正如componentWillUnmount
const FunctionalComponent = () => { React.useEffect(() => { return () => { console.log("Bye"); }; }, []); return <h1>Bye, World</h1>; };
調用方式
如果是一個函數組件,調用則是執行函數即可:
function 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>
獲取渲染的值
首先給出一個示例
函數組件對應如下:
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的內容仍舊是之前的內容
小結
兩種組件都有各自的優缺點
函數組件語法更短、更簡單,這使得它更容易開發、理解和測試
而類組件也會因大量使用 this而讓人感到困惑
