網站首頁 編程語言 正文
一、State
在React當中,當你更新組件的state,然后新的state就會重新渲染到頁面中。在這個時候不需要你操作任何DOM。這和vue
中組件的data
中的數據是相似的。
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> <!-- 生產環境中不建議使用 --> <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>現在是 {this.state.date.toLocaleTimeString()}.</p> <button onClick={this.handleClick}>更新時間</button> </div> ); } } ReactDOM.render(<Clock />, document.getElementById("app")); </script> </body> </html>
類組件需要在constructor
中定義this.state對象
,其對應的屬性就是需要使用的state,例如上面代碼中的title和date屬性,在render函數中通過this.sate.XXX
調用。
注意,修改state需要調用this.setState
方法,不可以直接對state進行賦值。
這里的handleClick是按鈕的點擊事件,點擊按鈕后,調用setState方法重新為date賦值,此時頁面會自動更新。
1.2 函數組件中的State
函數組件沒有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> <!-- 生產環境中不建議使用 --> <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>現在的n是 {n} .</p> <button onClick={addNum}>n+1</button> </div> ); }; ReactDOM.render(<Clock />, document.getElementById("app")); </script> </body> </html>
可以看到,在函數組件中使用state需要借助useState
,并且useState會返回setXXX方法用于修改定義的state,相比于類組件,函數組件更加簡潔,而且不用關注修改state時的this指向問題。
二、React生命周期
組件的生命周期可分成三個狀態:
- Mounting(掛載):已插入真實 DOM
- Updating(更新):正在被重新渲染
- Unmounting(卸載):已移出真實 DOM
2.1 掛載
當組件實例被創建并插入 DOM 中時,其生命周期調用順序如下:
-
constructor()
: 在 React 組件掛載之前,會調用它的構造函數。 -
getDerivedStateFromProps()
:在調用 render 方法之前調用,并且在初始掛載及后續更新時都會被調用。 -
render()
: render() 方法是 class組件中唯一必須實現的方法。 -
componentDidMount()
: 在組件掛載后(插入 DOM 樹中)立即調用。
render() 方法是 class 組件中唯一必須實現的方法,其他方法可以根據自己的需要來實現。
2.2 更新
每當組件的 state 或 props 發生變化時,組件就會更新。
當組件的 props 或 state 發生變化時會觸發更新。組件更新的生命周期調用順序如下:
-
getDerivedStateFromProps()
: 在調用 render 方法之前調用,并且在初始掛載及后續更新時都會被調用。根據shouldComponentUpdate() 的返回值,判斷 React 組件的輸出是否受當前 state 或 props更改的影響。 -
shouldComponentUpdate():
當 props 或 state 發生變化時,shouldComponentUpdate() 會在渲染執行之前被調用。 -
render()
: render() 方法是 class 組件中唯一必須實現的方法。 -
getSnapshotBeforeUpdate()
: 在最近一次渲染輸出(提交到 DOM節點)之前調用。 -
componentDidUpdate()
: 在更新后會被立即調用。
render() 方法是 class 組件中唯一必須實現的方法,其他方法可以根據自己的需要來實現。
2.3 卸載
當組件從 DOM 中移除時會調用如下方法:
componentWillUnmount()
: 在組件卸載及銷毀之前直接調用。
<!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> <!-- 生產環境中不建議使用 --> <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>
注意:只有類組件才有生命周期。函數組件每次都是重新運行函數,舊的組件即刻被銷毀。
2.4 函數式組件useEffect
與使用state需要借助useState一樣,在函數組件中,我們需要借助可以借助react提供的方法在函數式組件中實現“生命周期”,它就是useEffect
。
useEffect 給函數組件增加了操作副作用的能力。它跟 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> <!-- 生產環境中不建議使用 --> <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>現在的n是 {n} .</p> <button onClick={addNum}>n+1</button> </div> ); }; ReactDOM.render(<Clock />, document.getElementById("app")); </script> </body> </html>
可以看到,上面的使用useEffect時,掛載或者銷毀時,都會觸發useEffect中的函數,那么如何使用useEffect模擬生命周期呢?
// 只在組件掛載后顯示,只需要加個空數組做參數即可 useEffect(() => { document.title = `You clicked ${count} times`; },[]); // 銷毀階段 useEffect(() => { return ()=>{ console.log("銷毀階段") } });
三、總結
可以看到,類組件和函數組件在State和生命周期上區別還是非常大的,函數式組件需要調用react提供的hooks(鉤子函數,非常重要,后面會專門學習)來實現類組件對于的功能。
學習過程中,我發現react類組件類似于vue2的選項式api組件,而函數組件則vue3組合式api十分相似。
原文鏈接:https://blog.csdn.net/ZHANGYANG_1109/article/details/125885933
相關推薦
- 2022-07-12 mongoDB替換replace某個字段的部分內容
- 2022-10-07 Golang標準庫unsafe源碼解讀_Golang
- 2023-10-09 雙token登錄
- 2023-01-14 解決ubuntu安裝軟件時,status-code=409報錯的問題_Linux
- 2022-05-01 skywalking容器化部署docker鏡像構建k8s從測試到可用_docker
- 2022-09-27 OpenCV中findContours函數參數詳解_C 語言
- 2022-08-05 C語言示例講解if?else語句的用法_C 語言
- 2023-07-25 npm login 時報錯npm ERR! code E403
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支