React的Props、生命周期詳解
Props 的只讀性
“Props” 是 React 中用于傳遞數(shù)據(jù)給組件的一種機(jī)制,通常作為組件的參數(shù)進(jìn)行傳遞。在 React 中,props 是只讀的,意味著一旦將數(shù)據(jù)傳遞給組件的 props,組件就不能直接修改這些 props 的值。所以組件無(wú)論是使用函數(shù)聲明還是通過(guò) class 聲明,都決不能修改自身的 props。
所以React有一個(gè)嚴(yán)格的規(guī)則:所有 React 組件都必須像純函數(shù)一樣保護(hù)它們的 props 不被更改。
為什么Props是只讀的呢?
當(dāng)我們?cè)诟附M件中將數(shù)據(jù)傳遞給子組件時(shí),子組件只能使用這些 props 來(lái)讀取數(shù)據(jù),而不能修改它們。這是為了確保數(shù)據(jù)的單向流動(dòng),使得數(shù)據(jù)的流動(dòng)更加可控和可預(yù)測(cè)。當(dāng) Props 是只讀的時(shí)候,我們可以確保數(shù)據(jù)只能從父組件流向子組件,而子組件不能直接修改父組件傳遞的數(shù)據(jù)。這種單向數(shù)據(jù)流有助于維護(hù)組件的可預(yù)測(cè)性和代碼的可維護(hù)性。
如果我無(wú)法避免要在組件內(nèi)部修改數(shù)據(jù),該怎么辦?
如果你需要在組件內(nèi)部修改數(shù)據(jù),你可以使用組件的狀態(tài)(state)。狀態(tài)是組件內(nèi)部的可變數(shù)據(jù),可以通過(guò)特定的方法來(lái)修改。但是這些狀態(tài)無(wú)法直接傳遞給其他組件,如果需要在多個(gè)組件之間共享數(shù)據(jù),可以考慮使用上層組件的狀態(tài)或者全局狀態(tài)管理工具(如 Redux)
代碼示例:
import React, { useState } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
const incrementCount = () => {
setCount(count + 1);
};
return (
<div>
<h2>父組件</h2>
<p>Count: {count}</p>
<ChildComponent count={count} increment={incrementCount} />
</div>
);
}
function ChildComponent(props) {
return (
<div>
<h2>子組件t</h2>
<p>總和: {props.count}</p>
<button onClick={props.increment}>+1</button>
</div>
);
}
export default ParentComponent;如何將函數(shù)組件轉(zhuǎn)換成 class 組件 創(chuàng)建一個(gè)同名的 ES6 class,并且繼承于 React.Component。
- 添加一個(gè)空的
render()方法。 - 將函數(shù)體移動(dòng)到
render()方法之中。 - 在
render()方法中使用this.props替換props。 - 刪除剩余的空函數(shù)聲明。
函數(shù)式組件
function tick(Props) {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {Props.time.toLocaleTimeString()}.</h2>
</div>
);
root.render(element);
}class組件
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.date.toLocaleTimeString()}.</h2>
</div>
);
}
}生命周期
掛載
- constructor--------組件實(shí)例化時(shí)執(zhí)行,用于初始化state和綁定事件等操作
- getDerivedStateFromProps --------在render方法執(zhí)行之前調(diào)用,用于根據(jù)props設(shè)置state。
- render--------渲染組件
- componentDidMount(-------組件掛載到DOM后執(zhí)行,用于執(zhí)行一些需要DOM的操作,如獲取數(shù)據(jù)。
更新
- getDerivedStateFromProps-------在render方法執(zhí)行之前調(diào)用,用于根據(jù)props設(shè)置state
- shouldComponentUpdate------判斷組件是否需要重新渲染,默認(rèn)返回true
- render------渲染組件
- getSnapshotBeforeUpdate------在更新前獲取DOM信息,如滾動(dòng)位置等。
- componentDidUpdate--------組件更新后執(zhí)行,用于執(zhí)行一些需要DOM的操作,如更新數(shù)據(jù)
卸載
- componentWillUnmount------組件從DOM中移除時(shí)經(jīng)歷的階段

寫一個(gè)時(shí)鐘案例,每秒都會(huì)更新時(shí)間
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Clock />);讓我們來(lái)快速概括一下發(fā)生了什么和這些方法的調(diào)用順序:
- 當(dāng)
<Clock />被傳給root.render()的時(shí)候,React 會(huì)調(diào)用Clock組件的構(gòu)造函數(shù)。因?yàn)?Clock 需要顯示當(dāng)前的時(shí)間,所以它會(huì)用一個(gè)包含當(dāng)前時(shí)間的對(duì)象來(lái)初始化this.state。我們會(huì)在之后更新 state。 - 之后 React 會(huì)調(diào)用組件的
render()方法。這就是 React 確定該在頁(yè)面上展示什么的方式。然后 React 更新 DOM 來(lái)匹配Clock渲染的輸出。 - 當(dāng)
Clock的輸出被插入到 DOM 中后,React 就會(huì)調(diào)用ComponentDidMount()生命周期方法。在這個(gè)方法中,Clock 組件向?yàn)g覽器請(qǐng)求設(shè)置一個(gè)計(jì)時(shí)器來(lái)每秒調(diào)用一次組件的tick()方法。 - 瀏覽器每秒都會(huì)調(diào)用一次
tick()方法。 在這方法之中,Clock組件會(huì)通過(guò)調(diào)用setState()來(lái)計(jì)劃進(jìn)行一次 UI 更新。得益于setState()的調(diào)用,React 能夠知道state已經(jīng)改變了,然后會(huì)重新調(diào)用render()方法來(lái)確定頁(yè)面上該顯示什么。這一次,render()方法中的this.state.date就不一樣了,如此一來(lái)就會(huì)渲染輸出更新過(guò)的時(shí)間。 - React 也會(huì)相應(yīng)的更新 DOM。一旦 Clock 組件從 DOM 中被移除,React 就會(huì)調(diào)用
componentWillUnmount()生命周期方法,這樣計(jì)時(shí)器就停止了。
到此這篇關(guān)于React的Props、生命周期的文章就介紹到這了,更多相關(guān)React的Props、生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Webpack4和React hooks搭建項(xiàng)目的方法
這篇文章主要介紹了基于Webpack4和React hooks搭建項(xiàng)目的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02
關(guān)于React Native 無(wú)法鏈接模擬器的問題
許多朋友遇到React Native 無(wú)法鏈接模擬器的問題,怎么解決呢,本文給大家分享完整簡(jiǎn)便解決方法及配置例題,對(duì)React Native 鏈接模擬器相關(guān)知識(shí)感興趣的朋友一起看看吧2021-06-06
react 實(shí)現(xiàn)頁(yè)面代碼分割、按需加載的方法
本篇文章主要介紹了react 實(shí)現(xiàn)頁(yè)面代碼分割、按需加載的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
使用useMutation和React Query發(fā)布數(shù)據(jù)demo
這篇文章主要為大家介紹了使用useMutation和React Query發(fā)布數(shù)據(jù)demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
react創(chuàng)建項(xiàng)目啟動(dòng)報(bào)錯(cuò)的完美解決方法
這篇文章主要介紹了react創(chuàng)建項(xiàng)目啟動(dòng)報(bào)錯(cuò)的完美解決方法,全稱為Node Package Manager,是隨同NodeJS一起安裝的包管理工具,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08

