三分鐘搞懂react-hooks及實(shí)例代碼
背景
介紹Hooks之前,首先要說(shuō)一下React的組件創(chuàng)建方式,一種是類組件
,一種是純函數(shù)組件
,并且React團(tuán)隊(duì)希望,組件不要變成復(fù)雜的容器,最好只是數(shù)據(jù)流的管道。開(kāi)發(fā)者根據(jù)需要,組合管道即可。也就是說(shuō)組件的最佳寫法應(yīng)該是函數(shù)
,而不是類。
但是我們知道,在以往開(kāi)發(fā)中類組件和純函數(shù)組件的區(qū)別是很大的,純函數(shù)組件有著類組件不具備的多種特點(diǎn):
純函數(shù)組件沒(méi)有狀態(tài)
純函數(shù)組件沒(méi)有生命周期
純函數(shù)組件沒(méi)有this
這就注定,我們所推崇的函數(shù)組件,只能做UI展示的功能,涉及到狀態(tài)的管理與切換,我們不得不用類組件或者redux,但我們知道類組件的也是有缺點(diǎn)的,比如,遇到簡(jiǎn)單的頁(yè)面,代碼會(huì)顯得很重,并且每創(chuàng)建一個(gè)類組件,都要去繼承一個(gè)React實(shí)例;至于Redux,更不用多說(shuō),很久之前Redux的作者就說(shuō)過(guò),“能用React解決的問(wèn)題就不用Redux”。
useState
useState():狀態(tài)鉤子。純函數(shù)組件沒(méi)有狀態(tài),useState()用于為函數(shù)組件引入狀態(tài)。
點(diǎn)擊加一效果,分別用類組件和函數(shù)組件實(shí)現(xiàn)。可以看出用hooks寫出的代碼更加精簡(jiǎn)。
const [count,setCount] = useState(0)
;//數(shù)組解構(gòu),相當(dāng)于下面三句話
let _useState = useState(0);
let count = _useState[0];
let setState = _useState[1]
類組件
import React,{Component} from "react"; class App1 extends Component{ constructor(props) { super(props); this.state={ count:0 } } addCount(){ this.setState({count:this.state.count+1}) } render() { return( <div> <p>you clicked {this.state.count} times</p> <button onClick={this.addCount.bind(this)}>Click me</button> </div> ) } } export default App1;
函數(shù)組件
使用sueState重寫上面計(jì)數(shù)組件。
import React,{useState} from "react"; function App2(){ const [count,setCount] = useState(0);//數(shù)組解構(gòu) return( <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> </div> ) } export default App2;
多狀態(tài)聲明
使用多條語(yǔ)句聲明不同的狀態(tài)
import React,{useState} from "react"; function App3(){ const [name,setName] = useState('劉備');//數(shù)組解構(gòu) const [age,setAge] = useState(25); const [sex,setSex] = useState('男') return( <div> <p>姓名:{name}</p> <p>年齡:{age}</p> <p>性別:{sex}</p> </div> ) } export default App3;
useEffect
useEffect():副作用鉤子??梢杂脕?lái)更好的處理副作用,如異步請(qǐng)求等,Hooks的useEffect()也是為函數(shù)組件提供了處理副作用的鉤子。在類組件中我們會(huì)把請(qǐng)求放在componentDidMount里面,在函數(shù)組件中我們可以使用useEffect()。
useEffect相當(dāng)于componentDidMount和componentDidUpdate。
缺點(diǎn):由于它是異步的因此不能實(shí)時(shí)處理。
類組件中componentDidMount和componentDidUpdate
import React,{Component} from "react"; class App4 extends Component{ constructor(props) { super(props); this.state={ count:0 } } componentDidMount() { console.log(`componentDidMount=>you clicked ${this.state.count}`) } componentDidUpdate() { console.log(`componentDidUpdate=>you clicked ${this.state.count}`) } addCount(){ this.setState({count:this.state.count+1}) } render() { return( <div> <p>you clicked {this.state.count} times</p> <button onClick={this.addCount.bind(this)}>Click me</button> </div> ) } } export default App4;
useEffect模擬類組件中componentDidMount和componentDidUpdate
import React,{useState,useEffect} from "react"; function App5(){ const [count,setCount] = useState(0);//數(shù)組解構(gòu) useEffect(()=>{ console.log(`useEffect=>you clicked ${count} times`) }) return( <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> </div> ) } export default App5;
useEffect實(shí)現(xiàn)componmentWillUnment
先寫兩個(gè)路由跳轉(zhuǎn)頁(yè)面,并配置路由
import React,{useState,useEffect} from "react"; import { BrowserRouter as Router, Route, Link, Routes } from 'react-router-dom' function Index(){ return <h2>Index頁(yè)面</h2> } function List(){ return <h2>List頁(yè)面</h2> } function App5(){ const [count,setCount] = useState(0);//數(shù)組解構(gòu) return( <div> <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> </div> <Router> <div> <ul> <li><Link to="/">首頁(yè)</Link></li> <li><Link to="/list/">list</Link></li> </ul> <Routes> <Route path="/" exact element={<Index/>}/> <Route path="/list/" element={<List/>}/> </Routes> </div> </Router> </div> ) } export default App5;
使用useEffect表示進(jìn)入頁(yè)面的狀態(tài)。
解綁時(shí)使用return,這時(shí)發(fā)現(xiàn)我們點(diǎn)擊按鈕時(shí)也會(huì)發(fā)生改變,這是因?yàn)橹灰M件發(fā)生改變,它就會(huì)觸發(fā)解綁。解決方法使用第二個(gè)參數(shù)。
import React,{useState,useEffect} from "react"; import { BrowserRouter as Router, Route, Link, Routes } from 'react-router-dom' function Index(){ useEffect(()=>{ console.log(`useEffect=>Index頁(yè)面`) return ()=>{ console.log('跳轉(zhuǎn)頁(yè)面') } }) return <h2>Index頁(yè)面</h2> } function List(){ useEffect(()=>{ console.log(`useEffect=>List頁(yè)面`) }) return <h2>List頁(yè)面</h2> } function App5(){ const [count,setCount] = useState(0);//數(shù)組解構(gòu) return( <div> <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> </div> <Router> <div> <ul> <li><Link to="/">首頁(yè)</Link></li> <li><Link to="/list/">list</Link></li> </ul> <Routes> <Route path="/" exact element={<Index/>}/> <Route path="/list/" element={<List/>}/> </Routes> </div> </Router> </div> ) } export default App5;
解綁限制,第二個(gè)參數(shù)是一個(gè)數(shù)組,如果數(shù)組為空表示頁(yè)面被銷毀觸發(fā),如果有變量,表示只有這個(gè)變量狀態(tài)變化才會(huì)觸發(fā)。
import React,{useState,useEffect} from "react"; import { BrowserRouter as Router, Route, Link, Routes } from 'react-router-dom' function Index(){ useEffect(()=>{ console.log(`useEffect=>Index頁(yè)面`) return ()=>{ console.log('跳轉(zhuǎn)頁(yè)面') } },[]) return <h2>Index頁(yè)面</h2> } function List(){ useEffect(()=>{ console.log(`useEffect=>List頁(yè)面`) }) return <h2>List頁(yè)面</h2> } function App5(){ const [count,setCount] = useState(0);//數(shù)組解構(gòu) return( <div> <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> </div> <Router> <div> <ul> <li><Link to="/">首頁(yè)</Link></li> <li><Link to="/list/">list</Link></li> </ul> <Routes> <Route path="/" exact element={<Index/>}/> <Route path="/list/" element={<List/>}/> </Routes> </div> </Router> </div> ) } export default App5;
父子組件傳值useContext
useContext():共享狀態(tài)鉤子。作用就是可以做狀態(tài)的分發(fā),在React16.X以后支持,避免了react逐層通過(guò)Props傳遞數(shù)據(jù)。
使用步驟
1、先使用createContext創(chuàng)建上下文
2、然后使用Provider將值給提供出去
3、接收時(shí)用useContext接收就可以了
import React,{useState,createContext,useContext} from "react"; const CountContext = createContext(); function Counter(){ let count = useContext(CountContext); return (<h2>{count}</h2>) } function App6(){ const [count,setCount] = useState(0);//數(shù)組解構(gòu) return( <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> <CountContext.Provider value={count}> <Counter/> </CountContext.Provider> </div> ) } export default App6;
useReducer
useReducer():Action鉤子
。在使用React的過(guò)程中,如遇到狀態(tài)管理,一般會(huì)用到Redux,而React本身是不提供狀態(tài)管理的。而useReducer()提供了狀態(tài)管理。首先,關(guān)于redux我們都知道,其原理是通過(guò)用戶在頁(yè)面中發(fā)起action,從而通過(guò)reducer方法來(lái)改變state,從而實(shí)現(xiàn)頁(yè)面和狀態(tài)的通信。而Reducer的形式是(state, action) => newstate
。
import React,{useReducer} from "react"; function Reduser(){ const [count,dispath] = useReducer((state,action)=>{ switch (action){ case "add": return state+1 case "sub": return state-1 default: return state } },0) return( <div> <h2>現(xiàn)在的分?jǐn)?shù)是{count}</h2> <button onClick={()=>{dispath('add')}}>add</button> <button onClick={()=>{dispath('sub')}}>sub</button> </div> ) } export default Reduser
到此這篇關(guān)于三分鐘看完react-hooks的文章就介紹到這了,更多相關(guān)react hooks內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react如何同步獲取useState的最新?tīng)顟B(tài)值
這篇文章主要介紹了react如何同步獲取useState的最新?tīng)顟B(tài)值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01用react-redux實(shí)現(xiàn)react組件之間數(shù)據(jù)共享的方法
這篇文章主要介紹了用react-redux實(shí)現(xiàn)react組件之間數(shù)據(jù)共享的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06React實(shí)現(xiàn)下拉框的key,value的值同時(shí)傳送
這篇文章主要介紹了React實(shí)現(xiàn)下拉框的key,value的值同時(shí)傳送方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08關(guān)于React中setState同步或異步問(wèn)題的理解
相信很多小伙伴們都一直在疑惑,setState 到底是同步還是異步。本文就詳細(xì)的介紹一下React中setState同步或異步問(wèn)題,感興趣的可以了解一下2021-11-11jsoneditor二次封裝實(shí)時(shí)預(yù)覽json編輯器組件react版
這篇文章主要為大家介紹了jsoneditor二次封裝實(shí)時(shí)預(yù)覽json編輯器組件react版示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10使用React實(shí)現(xiàn)一個(gè)簡(jiǎn)單的待辦任務(wù)列表
這篇文章主要給大家介紹了使用React和Ant Design庫(kù)構(gòu)建的待辦任務(wù)列表應(yīng)用,它包含了可編輯的表格,用戶可以添加、編輯和完成任務(wù),以及保存任務(wù)列表數(shù)據(jù)到本地存儲(chǔ),文中有相關(guān)的代碼示例,需要的朋友可以參考下2023-08-08React Native中導(dǎo)航組件react-navigation跨tab路由處理詳解
這篇文章主要給大家介紹了關(guān)于React Native中導(dǎo)航組件react-navigation跨tab路由處理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10hooks寫React組件的5個(gè)注意細(xì)節(jié)詳解
這篇文章主要為大家介紹了hooks寫React組件的5個(gè)需要注意的細(xì)節(jié)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03