React State與生命周期詳細介紹
一、State
在React當(dāng)中,當(dāng)你更新組件的state,然后新的state就會重新渲染到頁面中。在這個時候不需要你操作任何DOM。這和vue中組件的data中的數(shù)據(jù)是相似的。
1.1 類組件中的State
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>State</title>
<script src="https://cdn.staticfile.org/react/16.8.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.8.0/umd/react-dom.development.js"></script>
<!-- 生產(chǎn)環(huán)境中不建議使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = { title: "React State", date: new Date() };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({ date: new Date() });
}
render() {
return (
<div>
<p>{this.state.title}</p>
<p>現(xiàn)在是 {this.state.date.toLocaleTimeString()}.</p>
<button onClick={this.handleClick}>更新時間</button>
</div>
);
}
}
ReactDOM.render(<Clock />, document.getElementById("app"));
</script>
</body>
</html>
類組件需要在constructor中定義this.state對象,其對應(yīng)的屬性就是需要使用的state,例如上面代碼中的title和date屬性,在render函數(shù)中通過this.sate.XXX調(diào)用。
注意,修改state需要調(diào)用this.setState方法,不可以直接對state進行賦值。
這里的handleClick是按鈕的點擊事件,點擊按鈕后,調(diào)用setState方法重新為date賦值,此時頁面會自動更新。
1.2 函數(shù)組件中的State
函數(shù)組件沒有state => React v16.8.0推出Hooks API,其中的一個API叫做useState可以解決問題。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>State</title>
<script src="https://cdn.staticfile.org/react/16.8.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.8.0/umd/react-dom.development.js"></script>
<!-- 生產(chǎn)環(huán)境中不建議使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
const Clock = (props) => {
const [n, setN] = React.useState(0);
function addNum() {
setN(n + 1);
}
return (
<div>
<p>現(xiàn)在的n是 {n} .</p>
<button onClick={addNum}>n+1</button>
</div>
);
};
ReactDOM.render(<Clock />, document.getElementById("app"));
</script>
</body>
</html>可以看到,在函數(shù)組件中使用state需要借助useState,并且useState會返回setXXX方法用于修改定義的state,相比于類組件,函數(shù)組件更加簡潔,而且不用關(guān)注修改state時的this指向問題。
二、React生命周期
組件的生命周期可分成三個狀態(tài):
- Mounting(掛載):已插入真實 DOM
- Updating(更新):正在被重新渲染
- Unmounting(卸載):已移出真實 DOM
2.1 掛載
當(dāng)組件實例被創(chuàng)建并插入 DOM 中時,其生命周期調(diào)用順序如下:
constructor(): 在 React 組件掛載之前,會調(diào)用它的構(gòu)造函數(shù)。getDerivedStateFromProps():在調(diào)用 render 方法之前調(diào)用,并且在初始掛載及后續(xù)更新時都會被調(diào)用。render(): render() 方法是 class組件中唯一必須實現(xiàn)的方法。componentDidMount(): 在組件掛載后(插入 DOM 樹中)立即調(diào)用。
render() 方法是 class 組件中唯一必須實現(xiàn)的方法,其他方法可以根據(jù)自己的需要來實現(xiàn)。
2.2 更新
每當(dāng)組件的 state 或 props 發(fā)生變化時,組件就會更新。
當(dāng)組件的 props 或 state 發(fā)生變化時會觸發(fā)更新。組件更新的生命周期調(diào)用順序如下:
getDerivedStateFromProps(): 在調(diào)用 render 方法之前調(diào)用,并且在初始掛載及后續(xù)更新時都會被調(diào)用。根據(jù)shouldComponentUpdate() 的返回值,判斷 React 組件的輸出是否受當(dāng)前 state 或 props更改的影響。shouldComponentUpdate():當(dāng) props 或 state 發(fā)生變化時,shouldComponentUpdate() 會在渲染執(zhí)行之前被調(diào)用。render(): render() 方法是 class 組件中唯一必須實現(xiàn)的方法。getSnapshotBeforeUpdate(): 在最近一次渲染輸出(提交到 DOM節(jié)點)之前調(diào)用。componentDidUpdate(): 在更新后會被立即調(diào)用。
render() 方法是 class 組件中唯一必須實現(xiàn)的方法,其他方法可以根據(jù)自己的需要來實現(xiàn)。
2.3 卸載
當(dāng)組件從 DOM 中移除時會調(diào)用如下方法:
componentWillUnmount(): 在組件卸載及銷毀之前直接調(diào)用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Lifecycle</title>
<script src="https://cdn.staticfile.org/react/16.8.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.8.0/umd/react-dom.development.js"></script>
<!-- 生產(chǎn)環(huán)境中不建議使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class Button extends React.Component {
constructor(props) {
super(props);
this.state = { data: 0 };
this.setNewNumber = this.setNewNumber.bind(this);
}
setNewNumber() {
this.setState({ data: this.state.data + 1 });
}
render() {
return (
<div>
<button onClick={this.setNewNumber}>INCREMENT</button>
<Content myNumber={this.state.data}></Content>
</div>
);
}
}
class Content extends React.Component {
componentWillMount() {
console.log("Component WILL MOUNT!");
}
componentDidMount() {
console.log("Component DID MOUNT!");
}
componentWillReceiveProps(newProps) {
console.log("Component WILL RECEIVE PROPS!");
}
shouldComponentUpdate(newProps, newState) {
return true;
}
componentWillUpdate(nextProps, nextState) {
console.log("Component WILL UPDATE!");
}
componentDidUpdate(prevProps, prevState) {
console.log("Component DID UPDATE!");
}
componentWillUnmount() {
console.log("Component WILL UNMOUNT!");
}
render() {
return (
<div>
<h3>{this.props.myNumber}</h3>
</div>
);
}
}
ReactDOM.render(
<div>
<Button />
</div>,
document.getElementById("app")
);
</script>
</body>
</html>
注意:只有類組件才有生命周期。函數(shù)組件每次都是重新運行函數(shù),舊的組件即刻被銷毀。
2.4 函數(shù)式組件useEffect
與使用state需要借助useState一樣,在函數(shù)組件中,我們需要借助可以借助react提供的方法在函數(shù)式組件中實現(xiàn)“生命周期”,它就是useEffect。
useEffect 給函數(shù)組件增加了操作副作用的能力。它跟 class 組件中的
componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不過被合并成了一個 API。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>useEffect</title>
<script src="https://cdn.staticfile.org/react/16.8.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.8.0/umd/react-dom.development.js"></script>
<!-- 生產(chǎn)環(huán)境中不建議使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
const Clock = (props) => {
const [n, setN] = React.useState(0);
function addNum() {
setN(n + 1);
}
React.useEffect(() => {
console.log(n);
});
return (
<div>
<p>現(xiàn)在的n是 {n} .</p>
<button onClick={addNum}>n+1</button>
</div>
);
};
ReactDOM.render(<Clock />, document.getElementById("app"));
</script>
</body>
</html>
可以看到,上面的使用useEffect時,掛載或者銷毀時,都會觸發(fā)useEffect中的函數(shù),那么如何使用useEffect模擬生命周期呢?
// 只在組件掛載后顯示,只需要加個空數(shù)組做參數(shù)即可
useEffect(() => {
document.title = `You clicked ${count} times`;
},[]);
// 銷毀階段
useEffect(() => {
return ()=>{
console.log("銷毀階段")
}
});三、總結(jié)
可以看到,類組件和函數(shù)組件在State和生命周期上區(qū)別還是非常大的,函數(shù)式組件需要調(diào)用react提供的hooks(鉤子函數(shù),非常重要,后面會專門學(xué)習(xí))來實現(xiàn)類組件對于的功能。
學(xué)習(xí)過程中,我發(fā)現(xiàn)react類組件類似于vue2的選項式api組件,而函數(shù)組件則vue3組合式api十分相似。
到此這篇關(guān)于React State與生命周期詳細介紹的文章就介紹到這了,更多相關(guān)React State內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
教你應(yīng)用?SOLID?原則整理?React?代碼之單一原則
這篇文章主要介紹了如何應(yīng)用?SOLID?原則整理?React?代碼之單一原則,今天,我們將從一個糟糕的代碼示例開始,應(yīng)用 SOLID 的第一個原則,看看它如何幫助我們編寫小巧、漂亮、干凈的并明確責(zé)任的 React 組件,需要的朋友可以參考下2022-07-07
ReactQuery系列之?dāng)?shù)據(jù)轉(zhuǎn)換示例詳解
這篇文章主要為大家介紹了ReactQuery系列之?dāng)?shù)據(jù)轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11
React實現(xiàn)組件間通信的幾種方式小結(jié)
在React應(yīng)用中,組件間的通信是一個基礎(chǔ)而關(guān)鍵的概念,理解和掌握不同組件之間的通信方式,可以幫助我們構(gòu)建出更加模塊化、可維護和可擴展的應(yīng)用程序,React提供了多種組件通信的方法,本文給大家詳細的介紹了這些方法,需要的朋友可以參考下2024-07-07

