教你react中如何理解usestate、useEffect副作用、useRef標識和useContext
1.usestate
1.1一般使用
注意:useState 的初始值(參數)只會在組件第一次渲染時生效。也就是說,以后的每次渲染,useState 獲取到都是最新的狀態(tài)值,React 組件會記住每次最新的狀態(tài)值。
其實與vue中的ref和reactive一樣,通過useState獲取到的數據可以實現組件視圖實時交互,而普通定義的數據僅僅在業(yè)務中使用。
使用規(guī)則:
1.每個useState 函數可以執(zhí)行多次,每次執(zhí)行互相獨立,每調用一次為函數組件提供一個狀態(tài) 。
2. 只能出現在函數組件或者其他hook函數中 。
3. 不能嵌套在if/for/其它函數中(react按照hooks的調用順序識別每一個hook)。
import { useState } from 'react' function App() { const [count, setCount] = useState(0) // 在這里可以進行打印測試 console.log(count) return ( <button onClick={() => { setCount(count + 1) }}>{count}</button> ) } export default App
初始值為泛型時:
interface LayerCheckbox { name: string; checked?: boolean; value?: string[]; disabled?: boolean; children?: LayerCheckbox[]; indeterminate?: boolean; key: string; // gis layer key relevance?: string; } const [checkboxArr, setCheckboxArr] = useState<LayerCheckbox[]>([ name: '高清影像圖', checked: true, key: LayerEnum.TILES_MAP, }, { name: '農場地塊信息', checked: true, key: LayerEnum.FIELD_AREA, }, { name: '灌溉設備圖層', checked: true, key: LayerEnum.DRAIN_IRRIGATE, }, { name: '農情設備圖層', checked: true, key: LayerEnum.CONDITION_DEVICE, }, ]);
1.2 useState回調函數作為參數
場景: useState初始值在回調函數里通過計算處理等函數操作得到
const [name, setName] = useState(()=>{ // 編寫計算邏輯 //return '計算之后的初始值' })
2.useEffect副作用
2.1 useEffect副作用及其使用
副作用是相對于主作用來說的,一個函數除了主作用,其他的作用就是副作用。對于 React 組件來說,主作用就是根據數據(state/props)渲染 UI,除此之外都是副作用(比如,手動修改 DOM)。
常見副作用:
1.數據請求 ajax發(fā)送
2.手動修改dom
3.localstorage操作
useEffect函數的作用就是為react函數組件提供副作用處理的!
代碼如下(示例):
import { useEffect, useState } from 'react' function App() { const [count, setCount] = useState(0) useEffect(()=>{ // dom操作 document.title = `當前已點擊了${count}次` }) return ( <button onClick={() => { setCount(count + 1) }}>{count}</button> ) } export default App
使用的三種場景:
1.不添加依賴項
組件首次渲染執(zhí)行一次,以及不管是哪個狀態(tài)更改引起組件更新時都會重新執(zhí)行。
1)組件初始渲染
2)組件更新 (不管是哪個狀態(tài)引起的更新)
useEffect(()=>{ console.log('副作用執(zhí)行了') })
2.添加空數組
組件只在首次渲染時執(zhí)行一次
useEffect(()=>{ console.log('副作用執(zhí)行了') },[]) })
3.添加特定依賴項
副作用函數在首次渲染時執(zhí)行,在依賴項(count)發(fā)生變化時重新執(zhí)行。
function App() { const [count, setCount] = useState(0) const [name, setName] = useState('zs') useEffect(() => { console.log('副作用執(zhí)行了') }, [count]) return ( <> <button onClick={() => { setCount(count + 1) }}>{count}</button> <button onClick={() => { setName('cp') }}>{name}</button> </> ) }
只要是 useEffect 回調函數中用到的數據(比如,count)就是依賴數據,就應該出現在依賴項數組[count]中,如果不添加依賴項就會有bug出現。
2.2 useEffect清理副作用
如果想要清理副作用 可以在副作用函數中的末尾return一個新的函數,在新的函數中編寫清理副作用的邏輯。
注意執(zhí)行時機為:
1.組件卸載時自動執(zhí)行
2.組件更新時(count一變時),下一個useEffect副作用函數執(zhí)行之前自動執(zhí)行
import { useEffect, useState } from "react" const App = () => { const [count, setCount] = useState(0) //頁面初始化就執(zhí)行一次,執(zhí)行后count+1,依賴count變化,又來執(zhí)行一次,此刻組件更新了,因此會清除副作用 useEffect(() => { const timerId = setInterval(() => { setCount(count + 1) }, 1000) return () => { // 用來清理副作用的事情 clearInterval(timerId) } }, [count]) return ( <div> {count} </div> ) } export default App
2.3 useEffect發(fā)送網絡請求
在內部單獨定義一個函數,然后把這個函數包裝成同步或者異步
useEffect(()=>{ async function fetchData(){ const res = await axios.get('http://geek.itheima.net/v1_0/channels') console.log(res) } },[])
3.自定義hook函數
useState與useEffect都屬于hook中的函數,那么也可以自己定義hook函數,利用useState和useEffect來實現自定義的hook函數,以便在其他地方調用。如:自定義一個hook函數,實現獲取滾動距離Y。在其他地方調用此函數,就可以拿到這個y進行渲染或其他處理操作。
//自定義hook import { useState } from "react" export function useWindowScroll () { const [y, setY] = useState(0) window.addEventListener('scroll', () => { const h = document.documentElement.scrollTop setY(h) }) return [y] //調用區(qū) import {useWindowScroll } from './hoooks/useWindowScroll ' const [y] = useWindowScroll () return( <div> {y} </div> )
自定義一個hook函數,監(jiān)聽依賴項(messge),實現一個功能(存儲帶本地):
//hook函數 import { useEffect, useState } from 'react' //message可以通過自定義傳入默認初始值 export function useLocalStorage (key, defaultValue) { const [message, setMessage] = useState(defaultValue) // 每次只要message變化 就會自動同步到本地ls useEffect(() => { window.localStorage.setItem(key, message) }, [message, key]) return [message, setMessage] } //調用區(qū) import {useLocalStorage } from './hoooks/useLocalStorage ' const [messge,setMessage] = useLocalStorage ('hook-key','阿飛') //初始值是 阿飛,5秒鐘后變成 cp setTimeout(()=>{ setMessage('cp') },5000)
4.useRef的使用
useRef能在函數組件中獲取真實的dom元素對象或者是組件對象。
首先執(zhí)行 useRef 函數并傳入null,返回值為一個對象內部有一個current屬性存放拿到的dom對象(組件實例),在使用時通過ref 綁定 要獲取的元素或者組件。
1)獲取dom <dom名 ref={ h1Ref }>
import { useEffect, useRef } from 'react' function App() { const h1Ref = useRef(null) useEffect(() => { console.log(h1Ref) },[]) return ( <div> <h1 ref={ h1Ref }>this is h1</h1> </div> ) } export default App
2)獲取組件實例 <組件名 ref={ h1Foo }>
//類組件 class Foo extends React.Component { sayHi = () => { console.log('say hi') } render(){ return <div>Foo</div> } } export default Foo //獲取組件實例 import { useEffect, useRef } from 'react' import Foo from './Foo' function App() { const h1Foo = useRef(null) useEffect(() => { console.log(h1Foo) }, []) return ( <div> <Foo ref={ h1Foo } /></div> ) } export default App
5.useContext的使用
實現步驟:
1.使用createContext 創(chuàng)建Context對象
2.在頂層組件通過Provider 提供數據
3.在底層組件通過useContext函數獲取數據
import { createContext, useContext } from 'react' // 創(chuàng)建Context對象 const Context = createContext() function A() { return <div>A中里面包裹C組件<C/></div> } function C() { // 底層組件通過useContext函數獲取數據 const name = useContext(Context) return <div>C中{name}</div> } function App() { return ( // 頂層組件通過Provider 提供數據 <Context.Provider value={'this is name'}> <div><Foo/></div> </Context.Provider> ) } export default App
一樣地,在頂層組件中Context.Provider這個value,然后在C組件中消費接受數據,由于A組件下面包裹著C組件,當A組件中執(zhí)行C組件時,可以看到里面可以拿到value數據。
實際還是在“被包裹的組件(C)”中消費接收數據。
不論中間隔著幾層,誰發(fā)數據誰provider,誰收數據誰useContext。
到此這篇關于react中如何理解usestate、useEffect副作用、useRef標識和useContext的文章就介紹到這了,更多相關react usestate useEffect副作用 useRef標識和useContext內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
React中組件的this.state和setState的區(qū)別
在React開發(fā)中,this.state用于初始化和讀取組件狀態(tài),而setState()用于安全地更新狀態(tài),正確使用這兩者對于管理React組件狀態(tài)至關重要,避免性能問題和常見錯誤2024-09-09React使用useEffect解決setState副作用詳解
這篇文章主要為大家介紹了React使用useEffect解決setState副作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10詳解React?如何防止?XSS?攻擊論$$typeof?的作用
這篇文章主要介紹了詳解React?如何防止?XSS?攻擊論$$typeof?的作用,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-07-07