react中Hooks的理解和用法小結(jié)
一、Hooks是什么?
Hook
是 React 16.8 的新增特性。它可以讓你在不編寫 class
的情況下使用 state
以及其他的 React
特性
至于為什么引入hook
,官方給出的動(dòng)機(jī)是解決長(zhǎng)時(shí)間使用和維護(hù)react
過(guò)程中常遇到的問(wèn)題,例如:
- 難以重用和共享組件中的與狀態(tài)相關(guān)的邏輯
- 邏輯復(fù)雜的組件難以開(kāi)發(fā)與維護(hù),當(dāng)我們的組件需要處理多個(gè)互不相關(guān)的 local state 時(shí),每個(gè)生命周期函數(shù)中可能會(huì)包含著各種互不相關(guān)的邏輯在里面
- 類組件中的this增加學(xué)習(xí)成本,類組件在基于現(xiàn)有工具的優(yōu)化上存在些許問(wèn)題
- 由于業(yè)務(wù)變動(dòng),函數(shù)組件不得不改為類組件等等
在以前,函數(shù)組件也被稱為無(wú)狀態(tài)的組件,只負(fù)責(zé)渲染的一些工作
因此,現(xiàn)在的函數(shù)組件也可以是有狀態(tài)的組件,內(nèi)部也可以維護(hù)自身的狀態(tài)以及做一些邏輯方面的處理
二、有哪些?具體用法
1、useState
作用:為函數(shù)式組件提供動(dòng)態(tài)屬性
語(yǔ)法:let [默認(rèn)數(shù)據(jù)變量, 修改數(shù)據(jù)的方法] = useState('默認(rèn)數(shù)據(jù)')
修改 基本數(shù)據(jù)類型:修改這個(gè)數(shù)據(jù)的方法(最新的數(shù)據(jù))
修改復(fù)雜數(shù)據(jù)類型 數(shù)組:修改數(shù)據(jù)方法(()=>{return [ ...新的數(shù)據(jù)]})
修改復(fù)雜數(shù)據(jù)類型 對(duì)象:修改數(shù)據(jù)方(()=>{...原數(shù)據(jù)state, 更新的屬性數(shù)據(jù)})
// 引入useState import { useState } from "react"; // hooks 為函數(shù)式組件提供一個(gè)屬性 // 作用 => 為函數(shù)式組件提供動(dòng)態(tài)數(shù)據(jù) // 語(yǔ)法 => let [默認(rèn)數(shù)據(jù)變量,修改這個(gè)數(shù)據(jù)的方法] = useState('默認(rèn)數(shù)據(jù)') // // 1. 修改的是 基本數(shù)據(jù)類型 // function App(){ // // 這里組件有一個(gè)動(dòng)態(tài)的數(shù)據(jù) // // let salary=1800; // // 動(dòng)態(tài)的數(shù)據(jù) =》 useState // let [salary,setSalary]=useState(1800); // const changeSalary=()=>{ // // 讓salary => 改變值 => useState 處理的是基本數(shù)據(jù)類型 // // setSalary(最新的數(shù)據(jù)) => salary 是最新的數(shù)據(jù) // setSalary(2000) // } // return ( // <div> // <h2>我的工資{salary}</h2> // <button onClick={()=>changeSalary()}>修改數(shù)據(jù)</button> // </div> // ); // } // // 2.修改復(fù)雜數(shù)據(jù)類型之 數(shù)組 // function App() { // // 動(dòng)態(tài)數(shù)據(jù) => 數(shù)組 // let [list, setList] = useState(["??", "?", "??"]); // const addItem = () => { // // 添加數(shù)據(jù) // let item = "??"; // setList((state) => { // state.push(item); // return [...state]; // }); // }; // const deleteItem =(index)=>{ // // 修改數(shù)據(jù) list => 調(diào)用 他的修改數(shù)據(jù)方法 setList // // console.log(list,index); // // list.splice(index,1); // // 處理復(fù)雜的數(shù)據(jù)類型 => (處理方法) // // 處理方法 特點(diǎn) // // 第一個(gè)參數(shù) 就是默認(rèn)數(shù)據(jù) // // 這個(gè)處理方法的返回值就是 最新的數(shù)據(jù) // setList((state)=>{ // state.splice(index,1); // 獲取到原理的數(shù)據(jù) => 根據(jù)索引刪除 // console.log(state); // return([...state]); // 改變引用地址 // }) // } // return ( // <div> // {list.map((item, index) => { // return <div key={index}>{item} <button onClick={()=>deleteItem(index)}>刪除</button></div>; // })} // <button onClick={() => addItem()}>添加</button> // </div> // ); // } // 3 修改復(fù)雜數(shù)據(jù)類型之 對(duì)象 function App() { // 定義一個(gè)動(dòng)他的數(shù)據(jù) 小明信息 let [obj, setObj] = useState({ name: "小明", salary: 1800 }); const changeSalary=()=>{ setObj(state=>{ // 1 獲取到原來(lái)的數(shù)據(jù)屬性,在添加我們需要更新的屬性 return {...state,salary:state.salary+200} }) } return ( <div> <h2> {obj.name}的月薪{obj.salary} 每日笑哈哈 <button onClick={()=>changeSalary()}>修改數(shù)據(jù) 學(xué)習(xí)后</button> </h2> </div> ); } export default App; /* 總結(jié) 函數(shù)式組件的動(dòng)態(tài)數(shù)據(jù)的處理 1 使用方式 useState 語(yǔ)法 let [默認(rèn)數(shù)據(jù),修改數(shù)據(jù)的方法]=useState(默認(rèn)值) 1 基本數(shù)據(jù)類型 => 修改數(shù)據(jù)方法(新的數(shù)據(jù)) 2 數(shù)組 => 修改數(shù)據(jù)的方法(()=>{ retrun[...新的數(shù)據(jù)] }) 3 對(duì)象 => 修改數(shù)據(jù)方法(處理方法中自己合并舊的數(shù)據(jù)) => 合并原理的數(shù)據(jù) */
2、useEffect 副作用
Effect Hook 可以讓你在函數(shù)組件中執(zhí)行副作用操作
作用:1. 函數(shù)式組件的生命周期 2. 偵聽(tīng)器
函數(shù)式組件的生命周期
組件加載完畢:語(yǔ)法: useEffect(處理函數(shù), 依賴項(xiàng)) ; 如果依賴項(xiàng)為空數(shù)組,useEffect( ()=>{ }, [ ]) 組件加載完畢,相當(dāng)于mounted,執(zhí)行一次,一般用來(lái)做dom操作,和發(fā)送請(qǐng)求
組件更新完畢:語(yǔ)法:useEffect(()=>{ }) ;如果沒(méi)有依賴項(xiàng),這個(gè)處理函數(shù),只要這個(gè)函數(shù)(組件)重新執(zhí)行,處理函數(shù)就會(huì)重新執(zhí)行(一般不使用)
組件摧毀:語(yǔ)法:useEffect(()=>{return()=>{ }};這個(gè)useEffect 處理函數(shù)式的返回值,并且是處理函數(shù)的返回值 是一個(gè)方法;用于 清除這個(gè)組件中全局定義的一些方法
import { useEffect,useState } from "react"; // useEffect => 副作用 // 1 當(dāng)組件的生命周期使用 // 寫法 1 useEffect(()=>{}) => 1.加載完畢 2.更新完畢 3.組件摧毀 // 1 加載完畢 => dom 操作,發(fā)動(dòng)網(wǎng)絡(luò)請(qǐng)求 獲取到后端的數(shù)據(jù) // 2 組件更新 // 想要的組件的加載 和更新 =》 在工作中不用 // function App(){ // let [salary,setSalary]=useState(1800); // useEffect(()=>{ // console.log(document.getElementById('h2')); // console.log('組件在瀏覽器上加載完畢,組件更新'); // }) // const addSaraly=()=>{ // setSalary(salary+200) // } // return( // <div> // <h2 id='h2'>useEffect 作用</h2> // <h3>{salary}</h3> // <button onClick={()=>addSaraly()}>++</button> // </div> // ) // } // // 2 發(fā)現(xiàn)我們需要這個(gè)副作用, 我們的生命周期(組件加載完畢) 執(zhí)行 mounted // // 語(yǔ)法 useEffect(()=>{},依賴項(xiàng)) // // // 如果這個(gè)依賴項(xiàng)為空的數(shù)組 useEffect(()=>{},[]) => 就相對(duì)于vue, 執(zhí)行一次 // function App(){ // let [salary,setSalary]=useState(1800); // console.log('組件created f') // 還是會(huì)重新創(chuàng)建組件 // useEffect(()=>{ // console.log(document.getElementById('h2')); // console.log('組件加載完畢'); // },[]) // // useEffect(處理函數(shù),依賴項(xiàng)) // // 處理函數(shù)和依賴項(xiàng)之間的關(guān)系 // // 1 如果沒(méi)有依賴項(xiàng),這個(gè)處理函數(shù),只要這個(gè)函數(shù)重新執(zhí)行,處理函數(shù)就會(huì)重新執(zhí)行 // // 2 如果有依賴項(xiàng),但是這個(gè)依賴項(xiàng)為空數(shù)組,那么這個(gè)處理函數(shù)只會(huì)執(zhí)行一次 // const addSaraly=()=>{ // setSalary(salary+200) // } // return( // <div> // <h2 id='h2'>useEffect 作用</h2> // <h3>{salary}</h3> // <button onClick={()=>addSaraly()}>++</button> // </div> // ) // } // function Children(){ // return( // <div> // </div> // ) // } // 2 相當(dāng)于 組件的摧毀 function App(){ let [salary,setSalary]=useState(1800); console.log('組件created f') // 還是會(huì)重新創(chuàng)建組件 const addSaraly=()=>{ setSalary(salary+200) } return( <div> <h2 id='h2'>useEffect 作用</h2> <h3>{salary}</h3> { salary==2000?<Children></Children>:<h4>444</h4> } <button onClick={()=>addSaraly()}>++</button> </div> ) } function Children(){ // 組件的摧毀的生命周期 // 寫法 => 是這個(gè)useEffect 處理函數(shù)式的返回值,并且是處理函數(shù)的返回值 是一個(gè)方法 let timer=setInterval(()=>{ console.log(1) },1000) useEffect(()=>{ return()=>{ console.log('組件摧毀了'); clearInterval(timer) // 清除全局 } }) return( <div> Children </div> ) } /* 總結(jié) 1 函數(shù)式組件的生命周期 2 另外的3個(gè) 是通過(guò) react hooks 提供 2.1 useEffect(()=>{},[]) =》 加載完畢 => 發(fā)送請(qǐng)求 dom操作 2.2 組件的更新 => 工作中不用 2.3 useEffect(()=>{return 方法}) =》 組件的摧毀 =》 清除這個(gè)組件全局定義的一個(gè)方法 */ export default App;
組件中的偵聽(tīng)器
1. 作用:偵聽(tīng)器,相當(dāng)于vue中的watch
語(yǔ)法:useEffect(()=>{},[監(jiān)聽(tīng)的數(shù)據(jù)1,監(jiān)聽(tīng)的數(shù)據(jù)2]) ;useEffect(()=>{},[依賴的數(shù)據(jù)源]),相當(dāng)于立即執(zhí)行的偵聽(tīng)器,監(jiān)聽(tīng)的函數(shù)發(fā)生改變,處理函數(shù)就會(huì)改變
useEffectb本質(zhì)就是一個(gè)宏任務(wù)
import { useEffect,useState } from "react"; // useEffect =》 相當(dāng)于vue中的watch function App(){ let [salary,setSalary]=useState(1800); let [name,setName]=useState('小紅'); console.log('組件created f','還會(huì)不會(huì)重新創(chuàng)建組件?') // 還會(huì)不會(huì)重新創(chuàng)建組件? // watch => 立即執(zhí)行 useEffect(()=>{ console.log(salary) },[salary]) const addSaraly=()=>{ setSalary(salary+200) } return( <div> <h2 id='h2'>useEffect 作用</h2> <h3>{salary}</h3> <button onClick={()=>addSaraly()}>++</button> <h3>{name}</h3> <button onClick={()=>setName('小明')}>修改</button> </div> ) } // 總結(jié): useEffect(()=>{},[依賴的數(shù)據(jù)源]),相對(duì)于立即執(zhí)行的偵聽(tīng)器 // useEffect 本質(zhì)就是一個(gè)宏任務(wù) export default App;
3、useContext和React.createContext
useContext
作用:全局提供數(shù)據(jù),用來(lái)做全局設(shè)置
用法: useContext 必須要和 React.createContext 一起使用
創(chuàng)建一個(gè)全局?jǐn)?shù)據(jù):let Context=React.createContext() // 返回一個(gè)對(duì)象:有一個(gè)屬性provider 是提供數(shù)據(jù)的
在父子組件中提供數(shù)據(jù):<Context.Provider value={所提供的數(shù)據(jù)} ></Context.Provider>
在子組件中獲取父組件提供的數(shù)據(jù):let data=useContext(Context) // 相當(dāng)于inject,data就是在父組件中獲取到的數(shù)據(jù)
// useContext => 提供上下文 =》 本質(zhì)=》全局變量 import React,{ useContext } from "react"; // 在最外層提供數(shù)據(jù), 在里面可以獲取到數(shù)據(jù) // 業(yè)務(wù)中的使用 => 全局設(shè)置主體,字體 dengdeng // 使用:必須 提供數(shù)據(jù)provideer =》 React.createContext() let Context =React.createContext() // 返回一個(gè)對(duì)象 => 有一個(gè)屬性 provider => 提供數(shù)據(jù) console.log(Context) let theme={ background:'red' }; function App(){ return( // 在父級(jí)組件中提供數(shù)據(jù) <Context.Provider value={theme}> <div> <Children></Children> </div> </Context.Provider> ) } // 創(chuàng)建子組件 function Children(){ // 在子組件中需要獲取到父級(jí)組件提供的數(shù)據(jù) let datas=useContext(Context); // inject() console.log(datas) // {background: 'red'} return( <div style={{background:datas.background}}> Children </div> ) } // 總結(jié) useContext =》 獲取到 React.createContext() 提供的數(shù)據(jù) export default App;
4、useReducer
用法:和useState 一樣,都是用來(lái)處理動(dòng)態(tài)數(shù)據(jù)
作用:就是對(duì)動(dòng)態(tài)的數(shù)據(jù)的行為(這個(gè)動(dòng)態(tài)數(shù)據(jù)修改的方法)進(jìn)行約束
語(yǔ)法:語(yǔ)法: let [默認(rèn)數(shù)據(jù),dispatch] = useReducer(reducer,默認(rèn)數(shù))
核心:
retucer:reducer相當(dāng)于vuex中的mutations,作用:定義行為(方法),修改動(dòng)態(tài)數(shù)據(jù)
reducer是一個(gè)函數(shù)
這個(gè)函數(shù)有兩個(gè)參數(shù), 參數(shù)1 :數(shù)據(jù) 參數(shù)2: 行為
這個(gè)函數(shù)的返回值,就是最新的數(shù)據(jù)
只能處理同步函數(shù)
用來(lái)觸發(fā)reducer行為,dispatch({actions}) => 這個(gè)actions是一個(gè)對(duì)象
import {useState, useReducer } from 'react' // useReducer // 用法 和useState 一樣,都是用來(lái)處理動(dòng)態(tài)數(shù)據(jù) // 作用 => 就是對(duì)動(dòng)態(tài)的數(shù)據(jù)的行為(這個(gè)動(dòng)態(tài)數(shù)據(jù)修改的方法)進(jìn)行約束 // 語(yǔ)法 => let [默認(rèn)數(shù)據(jù),觸發(fā)reducer行為]=useReducer(reducer,默認(rèn)數(shù)據(jù)) // reducer => 相當(dāng)于vuex中 mutations // 作用 => 定義行為(方法) => 修改動(dòng)態(tài)數(shù)據(jù) // reducer 是什么 // 1 它是一個(gè)函數(shù) // 2 這個(gè)函數(shù)有兩個(gè)參數(shù), 參數(shù)1 就是你的數(shù)據(jù) 參數(shù)2 行為 // 3 這個(gè)函數(shù)返回值 就是你最新的數(shù)據(jù) // 4 只能處理同步問(wèn)題 // 定義reducer function reducer(state,actions){ // 定義你處理邏輯 => add reduce switch(actions.type){ case 'add': console.log(state); // 默認(rèn)參數(shù) console.log(actions); // 行為 return state+actions.money case 'reduce': return state-200; default : return state; } } function App(){ let [money,setMoney]=useState(1800); let [moneys,dispatch]=useReducer(reducer,1000) const changeM=()=>{ setMoney('椅子') } return( <div> <h2>{money}</h2> <button onClick={()=>changeM()}>操作money</button> <h2>{moneys}</h2> {/* 觸發(fā)reducer => dispatch 觸發(fā)reduce行為 dispatch(就是reducer actions) => 這個(gè)actions 是一個(gè)對(duì)象 傳遞對(duì)象 */} <button onClick={()=>dispatch({type:'add',money:300})}>add</button> </div> ) } export default App /* 總結(jié): userReducer 核心 reducer => 用來(lái)定義處理動(dòng)態(tài)數(shù)據(jù)的行為的 dispatch => 觸發(fā) reducer 中的行為 */
5、useRef
作用:獲取到元素的真實(shí)dom
語(yǔ)法:let dom=useRef(null) ; (此時(shí)dom=null);在標(biāo)簽元素上<div ref={dom}></div>; (dom就可以獲取到真實(shí)的dom)
組件的創(chuàng)建流程:
組件創(chuàng)建完畢:初始化這個(gè)組件的屬性
再將這個(gè)組件的模板語(yǔ)法(jsx)變?yōu)関node(1. 如果有事件就集中處理,2. 如果又屬性 就進(jìn)行綁定)
再將這個(gè)組件變?yōu)檎鎸?shí)dom
做一些dom操作
import {useRef,useEffect} from 'react' // useRef // 作用 :獲取到元素的真實(shí)dom // 在created 生命周期中進(jìn)行定義useRef // 用法 let dom=useRef(null) function App(){ let dom =useRef(null) // null let datas=100; useEffect(()=>{ console.log(dom);// 獲取到真實(shí)的dom console.log(document.getElementById('h2s')); },[]) return( <div> <h2 id='h2s' data-id={datas} ref={dom}>dom</h2> </div> ) } /* 這個(gè)組件在創(chuàng)建的流程 1 組件創(chuàng)建完畢 => 初始化 這個(gè)組件的屬性 2 將這個(gè)組件 模板語(yǔ)法(jsx) => 變成vnode( 1 如果有事件 集中處理,2 有屬性 進(jìn)行綁定) =》 再將這個(gè)vnode 變成真實(shí)dom 3 做一些dom操作 */ export default App;
6、useLayoutEffect
作用:
監(jiān)聽(tīng)器:當(dāng)監(jiān)聽(tīng)的數(shù)據(jù) 發(fā)生改變之前就執(zhí)行這個(gè)處理方法
生命周期:語(yǔ)法:和useEffect一樣 useLayout(處理函數(shù),依賴項(xiàng))
組件更新之前:沒(méi)有依賴項(xiàng),只要組件更新,函數(shù)就會(huì)在組件更新前更新
掛載完成之前:依賴項(xiàng)為空數(shù)組,相當(dāng)于mounted,執(zhí)行一次
組件摧毀之前:useEffect(()=>return 方法) 返回的方法在組件摧毀前執(zhí)行
useLayoutEffect:底層代碼是 微任務(wù)
import {useEffect,useLayoutEffect,useState} from 'react' function App(){ // useLayoutEffect // 寫法 和useEffect 一樣的 /* useLayoutEffect 作用 1 生命周期 瀏覽器加載之前 ,更新之前 , 摧毀之前 2 監(jiān)聽(tīng) 當(dāng)這個(gè)數(shù)據(jù) 發(fā)生改變之前就是執(zhí)行這個(gè)處理方法 */ let [age,setAge]=useState(100); // useEffect(()=>{ // console.log('加載完畢 useEffect'); // },[]) // useLayoutEffect(()=>{ // console.log('瀏覽器生成dom 之前 useEffect') // },[]) useEffect(()=>{ console.log('加載完畢 useEffect'); },[age]) useLayoutEffect(()=>{ console.log(age) console.log('瀏覽器生成dom 之前 useEffect') },[age]) return( <div> {age} <button onClick={()=>setAge(age+1)}>++</button> </div> ) } export default App; // useLayoutEffect =》 底層代碼是 微任務(wù)
7、useMemo
作用:1. 緩存組件 2. 緩存變量
緩存組件:
語(yǔ)法:let 組件= React.memo(需要緩存的組件)
<組件></組件>
特點(diǎn):緩存組件 如果這個(gè)組件的屬性沒(méi)有變化就不會(huì)創(chuàng)建,反之就會(huì)重新創(chuàng)建
react組件更新機(jī)制:組件的重新創(chuàng)建,只要數(shù)據(jù)發(fā)生改變,組件就會(huì)重新創(chuàng)建,會(huì)造成性能問(wèn)題
組件的渲染:先渲染父組件,在渲染子組件
問(wèn)題1:在子組件中更新數(shù)據(jù),如果沒(méi)有將子組件進(jìn)行模塊化劃分,那么父組件也會(huì)重新創(chuàng)建,會(huì)導(dǎo)致性能問(wèn)題
解決方法:
模塊化開(kāi)發(fā):組件的模塊化劃分,將子組件進(jìn)行抽離(一個(gè)功能一個(gè)模塊),此時(shí):(子組件數(shù)據(jù)更新,該子組件會(huì)重新創(chuàng)建,其父組件與兄弟組件不會(huì)重新創(chuàng)建)
問(wèn)題2:如果我們?cè)诟附M件中更新數(shù)據(jù) => 會(huì)重新渲染組件 => 這個(gè)父組件的嵌套組件(子組件),也會(huì)被重新渲染 => 會(huì)導(dǎo)致性能問(wèn)題
解決方法:
1. 緩存組件:React.mome(需要被緩存的組件); 緩存組件,不管父組件是否重新創(chuàng)建,這個(gè)子組件創(chuàng)建一次,如果子組件的數(shù)據(jù)沒(méi)有改變,就不需要重新創(chuàng)建
// react 更新機(jī)制 => 組件重新創(chuàng)建 import React, { useState } from "react"; // // 組件模塊化劃分 // function App() { // console.log("father 組件重新創(chuàng)建了"); // return ( // <div> // {/* 模塊化劃分 */} // <Children2></Children2> // <Children1></Children1> // </div> // ); // } // function Children2() { // console.log("children2222222222 組件重新創(chuàng)建"); // let [salary, setSalary] = useState(1800); // const changeSalary = () => { // setSalary(salary + 200); // }; // return ( // <div> // 月入{salary} // <button onClick={() => changeSalary()}>更新數(shù)據(jù)+200</button> // </div> // ); // } // function Children1() { // console.log("children111111 組件重新創(chuàng)建"); // return <div>children</div>; // } function App() { console.log("father 組件重新創(chuàng)建了"); let [salary, setSalary] = useState(1800); const changeSalary = () => { setSalary(salary + 200); }; return ( <div> 月入{salary} <button onClick={() => changeSalary()}>更新數(shù)據(jù)+200</button> {/* 不管父組件是否重新創(chuàng)建,這個(gè)子組件創(chuàng)建一次,如果子組件的數(shù)據(jù)沒(méi)有改變,就不需要重新創(chuàng)建 */} <Keepchildren1></Keepchildren1> </div> ); } /* React.memo()=> 緩存組件 語(yǔ)法: React.memo(需要緩存的組件) => 緩存組件 特點(diǎn): 緩存組件 如果這個(gè)組件屬性值沒(méi)有變化就不會(huì)創(chuàng)建,反之,就會(huì)重新創(chuàng)建 */ function Children1() { console.log("children111111 組件重新創(chuàng)建"); return (<div>children</div>) } let Keepchildren1=React.memo(Children1) export default App; // 1 組件的渲染 => 先渲染父組件,再渲染子組件 // 2 如果我們?cè)诟附M件中更新數(shù)據(jù) => 會(huì)重新渲染組件 => 這個(gè)父組件的嵌套組件(子組件),也會(huì)被重新渲染 => 會(huì)導(dǎo)致性能問(wèn)題 // 解決方法(子組件數(shù)據(jù)更新,該子組件會(huì)重新創(chuàng)建,其父組件與兄弟組件不會(huì)重新創(chuàng)建) // 1 模塊化開(kāi)發(fā) => 一個(gè)功能一個(gè)模塊
緩存變量
1. 作用:緩存變量
2. 語(yǔ)法:let 緩存變量 = useMemo( ()=>{ return 緩存數(shù)據(jù)},[監(jiān)聽(tīng)的數(shù)據(jù)源] ); // 當(dāng)依賴的數(shù)據(jù)發(fā)生改變的時(shí)候才會(huì)更新
// react 更新機(jī)制 => 組件重新創(chuàng)建 import React, { useState,useMemo } from "react"; // useMemo 作用: 緩存變量 // 用法: let 緩存變量 = useMemo(()=>{},[監(jiān)聽(tīng)的數(shù)據(jù)源]) // 當(dāng)依賴的數(shù)據(jù)發(fā)生改變的時(shí)候才會(huì)更新 function App() { console.log("father 組件重新創(chuàng)建了"); let [salary, setSalary] = useState(1800); // let name="張三"; // 這個(gè)數(shù)據(jù)寫死 => 不用更新 let Kname=useMemo(()=>{ console.log('更新'); return '張三'; // 緩存數(shù)據(jù) 當(dāng)依賴的數(shù)據(jù)發(fā)生改變的時(shí)候才會(huì)更新 },[salary]) const changeSalary = () => { setSalary(salary + 200); }; return ( <div> <h2>{Kname}</h2> 月入{salary} <button onClick={() => changeSalary()}>更新數(shù)據(jù)+200</button> </div> ); } export default App;
8、useCallback
作用:緩存方法
語(yǔ)法:let 緩存方法 = useCallback( ()=>{} , []); // 當(dāng)依賴的數(shù)據(jù)發(fā)生改變的時(shí)候才會(huì)更新
import React, { useState,useMemo, useCallback } from "react"; // useCallback 作用: 緩存方法 // 用法: let 緩存方法 = useCallback(()=>{},[]) // 當(dāng)依賴的數(shù)據(jù)發(fā)生改變的時(shí)候才會(huì)更新 function App() { console.log("father 組件重新創(chuàng)建了"); let [salary, setSalary] = useState(1800); const getdata=()=>{ console.log(1200); } let Keepgetdata=useCallback(()=>{ return getdata(); },[salary]) const changeSalary = () => { setSalary(salary + 200); }; return ( <div> 月入{salary} <button onClick={() => changeSalary()}>更新數(shù)據(jù)+200</button> <button onClick={()=>Keepgetdata()}>緩存方法</button> </div> ); } export default App;
9、自定義hooks
概念:
它是一個(gè)方法
這個(gè)方法是以u(píng)se 開(kāi)頭的
在這個(gè)方法中可以使用 react 提供的api
到此這篇關(guān)于react中Hooks的理解和用法的文章就介紹到這了,更多相關(guān)react中Hooks用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react中ref獲取dom或者組件的實(shí)現(xiàn)方法
這篇文章主要介紹了react中ref獲取dom或者組件的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05react-dnd實(shí)現(xiàn)任意拖動(dòng)與互換位置
這篇文章主要為大家詳細(xì)介紹了react-dnd實(shí)現(xiàn)任意拖動(dòng)與互換位置,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08解決React報(bào)錯(cuò)Unexpected default export of an
這篇文章主要為大家介紹了React報(bào)錯(cuò)Unexpected default export of anonymous function解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12react拖拽組件react-sortable-hoc的使用
本文主要介紹了react拖拽組件react-sortable-hoc的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02react-redux集中式狀態(tài)管理及基本使用與優(yōu)化
react-redux把組件分為兩類,一類叫做UI組件,一類叫做容器組件,這篇文章主要介紹了集中式狀態(tài)管理<react-redux>基本使用與優(yōu)化,需要的朋友可以參考下2022-08-08react-navigation 如何判斷用戶是否登錄跳轉(zhuǎn)到登錄頁(yè)的方法
本篇文章主要介紹了react-navigation 如何判斷用戶是否登錄跳轉(zhuǎn)到登錄頁(yè)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12解決React在安裝antd之后出現(xiàn)的Can''t resolve ''./locale''問(wèn)題(推薦)
這篇文章主要介紹了解決React在安裝antd之后出現(xiàn)的Can't resolve './locale'問(wèn)題,本文給大家分享解決方案,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05React?Suspense解決競(jìng)態(tài)條件詳解
這篇文章主要為大家介紹了React?Suspense解決競(jìng)態(tài)條件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11react中使用ant組件庫(kù)的modal彈窗報(bào)錯(cuò)問(wèn)題及解決
這篇文章主要介紹了react中使用ant組件庫(kù)的modal彈窗報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03