React useMemo和useCallback的使用場(chǎng)景
useMemo
我們知道當(dāng)父組件發(fā)生重新渲染時(shí),其所有(狀態(tài)、局部變量等)都是新的。一旦子組件依賴于父組件的某一個(gè)對(duì)象變量,那么無論對(duì)象是否發(fā)生變化,子組件拿到的都是新的對(duì)象,從而使子組件對(duì)應(yīng)的 diff 失效,依舊會(huì)重新執(zhí)行該部分邏輯。在下面的例子中,我們的副作用依賴項(xiàng)中包含了父組件傳入的對(duì)象參數(shù),每次父組件發(fā)生更新時(shí),都會(huì)觸發(fā)數(shù)據(jù)請(qǐng)求。
function Info({ style, }) { console.log('Info 發(fā)生渲染'); useEffect(() => { console.log('重新加載數(shù)據(jù)'); // 每次發(fā)生重新渲染時(shí),都會(huì)重新加載數(shù)據(jù) }, [style]); return ( <p style={style}> 這是 Info 里的文字 </p> ); } function Page() { console.log('Page 發(fā)生渲染'); const [count, setCount] = useState(0); const style = { color: 'red' }; // 計(jì)數(shù)器 +1 時(shí),引發(fā) Page 的重新渲染,進(jìn)而引發(fā) Info 的重新渲染 return ( <div> <h4>計(jì)數(shù)值為:{count}</h4> <button onClick={() => setCount(count + 1)}> +1 </button> <Info style={style} /> </div> ); }
React Hooks 給我們提供了解決方案,useMemo 允許我們緩存?zhèn)魅氲膶?duì)象,僅當(dāng)依賴項(xiàng)發(fā)生變化時(shí),才重新計(jì)算并更新相應(yīng)的對(duì)象。
function Page() { console.log('Page 發(fā)生渲染'); const [color] = useState('red'); const [count, setCount] = useState(0); const style = useMemo(() => ({ color }), [color]); // 只有 color 發(fā)生實(shí)質(zhì)性改變時(shí),style 才會(huì)變化 // 計(jì)數(shù)器 +1 時(shí),引發(fā) Page 的重新渲染,進(jìn)而引發(fā) Info 的重新渲染 // 但是由于 style 緩存了,因此不會(huì)觸發(fā) Info 內(nèi)的數(shù)據(jù)重新加載 return ( <div> <h4>計(jì)數(shù)值為:{count}</h4> <button onClick={() => setCount(count + 1)}> +1 </button> <Info style={style} /> </div> ); }
useCallback
React Hooks 在數(shù)據(jù)流上帶來的變化有兩點(diǎn):一是支持更友好的使用 context 進(jìn)行狀態(tài)管理,避免層級(jí)過多時(shí)向中間層承載無關(guān)參數(shù);二是允許函數(shù)參與到數(shù)據(jù)流中,避免向下層組件傳入多余的參數(shù)。
useContext 作為 hooks 的核心模塊之一,可以獲取到傳入 context 的當(dāng)前值,以此達(dá)到跨層通信的目的。React 官網(wǎng)有著詳細(xì)的介紹,需要關(guān)注的是一旦 context 值發(fā)生改變,所有使用了該 context 的組件都會(huì)重新渲染。為了避免無關(guān)的組件重繪,我們需要合理的構(gòu)建 context ,比如從第一節(jié)提到的新思維模式出發(fā),按狀態(tài)的相關(guān)度組織 context,將相關(guān)狀態(tài)存儲(chǔ)在同一個(gè) context 中。
在過去,如果父子組件用到同一個(gè)數(shù)據(jù)請(qǐng)求方法 getData ,而該方法又依賴于上層傳入的 query 值時(shí),通常需要將 query 和 getData 方法一起傳遞給子組件,子組件通過判斷 query 值來決定是否重新執(zhí)行 getData。
class Parent extends React.Component { state = { query: 'keyword', } getData() { const url = `https://mocks.alibaba-inc.com/mock/fO87jdfKqX/demo/queryData.json?query=${this.state.query}`; // 請(qǐng)求數(shù)據(jù)... console.log(`請(qǐng)求路徑為:${url}`); } render() { return ( // 傳遞了一個(gè)子組件不渲染的 query 值 <Child getData={this.getData} query={this.state.query} /> ); } } class Child extends React.Component { componentDidMount() { this.props.getData(); } componentDidUpdate(prevProps) { // if (prevProps.getData !== this.props.getData) { // 該條件始終為 true // this.props.getData(); // } if (prevProps.query !== this.props.query) { // 只能借助 query 值來做判斷 this.props.getData(); } } render() { return ( // ... ); } }
在 React Hooks 中 useCallback 支持我們緩存某一函數(shù),當(dāng)且僅當(dāng)依賴項(xiàng)發(fā)生變化時(shí),才更新該函數(shù)。這使得我們可以在子組件中配合 useEffect ,實(shí)現(xiàn)按需加載。通過 hooks 的配合,使得函數(shù)不再僅僅是一個(gè)方法,而是可以作為一個(gè)值參與到應(yīng)用的數(shù)據(jù)流中。
function Parent() { const [count, setCount] = useState(0); const [query, setQuery] = useState('keyword'); const getData = useCallback(() => { const url = `https://mocks.alibaba-inc.com/mock/fO87jdfKqX/demo/queryData.json?query=${query}`; // 請(qǐng)求數(shù)據(jù)... console.log(`請(qǐng)求路徑為:${url}`); }, [query]); // 當(dāng)且僅當(dāng) query 改變時(shí) getData 才更新 // 計(jì)數(shù)值的變化并不會(huì)引起 Child 重新請(qǐng)求數(shù)據(jù) return ( <> <h4>計(jì)數(shù)值為:{count}</h4> <button onClick={() => setCount(count + 1)}> +1 </button> <input onChange={(e) => {setQuery(e.target.value)}} /> <Child getData={getData} /> </> ); } function Child({ getData }) { useEffect(() => { getData(); }, [getData]); // 函數(shù)可以作為依賴項(xiàng)參與到數(shù)據(jù)流中 return ( // ... ); }
以上就是React useMemo和useCallback的使用場(chǎng)景的詳細(xì)內(nèi)容,更多關(guān)于React useMemo和useCallback的使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
搭建React?Native熱更新平臺(tái)的詳細(xì)過程
這篇文章主要介紹了搭建React?Native熱更新平臺(tái),要實(shí)現(xiàn)?React?Native?熱更新功能,有四種思路?Code?Push、Pushy、Expo?和自研,感興趣的朋友一起通過本文學(xué)習(xí)吧2022-05-05react中的watch監(jiān)視屬性-useEffect介紹
這篇文章主要介紹了react中的watch監(jiān)視屬性-useEffect使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09React Hook useState useEffect componentD
這篇文章主要介紹了React Hook useState useEffect componentDidMount componentDidUpdate componentWillUnmount問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03Rect Intersection判斷兩個(gè)矩形是否相交
這篇文章主要為大家介紹了Rect Intersection判斷兩個(gè)矩形是否相交的算法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06react實(shí)現(xiàn)頭部導(dǎo)航,選中狀態(tài)底部出現(xiàn)藍(lán)色條塊問題
這篇文章主要介紹了react實(shí)現(xiàn)頭部導(dǎo)航,選中狀態(tài)底部出現(xiàn)藍(lán)色條塊問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11React實(shí)現(xiàn)虛擬滾動(dòng)的三種思路詳解
在??web??開發(fā)的過程中,或多或少都會(huì)遇到大列表渲染的場(chǎng)景,為了解決大列表造成的渲染壓力,便出現(xiàn)了虛擬滾動(dòng)技術(shù),本文主要介紹虛擬滾動(dòng)的三種思路,希望對(duì)大家有所幫助2024-04-04