React高級概念之Context用法詳解
Context 的基本用法
總體而言,使用 Context 分為如下三步:
創(chuàng)建 Context 對象
Context 只能使用 React.createContext 方法創(chuàng)建,代碼如下:
// 注釋Context中數(shù)據(jù)的類型 interface IMyContext { ????lang: string; ????changeLang: (lang: string) => void } // React.createContext的參數(shù)是Context中數(shù)據(jù)的默認(rèn)值。 const MyContext = React.createContext<IMyContext >({ ????lang: 'zh_CN', ????changeLang: () => { throw Error('你必須自己實(shí)現(xiàn)這個(gè)方法') } })
用創(chuàng)建的 Context.Provider 包裹組件樹。
用 Context.Provider 圈選 Context 的作用域,只有作用域內(nèi)的組件才能消費(fèi) Context 中的數(shù)據(jù),此處是管道的入口,在這里放入想要傳遞的數(shù)據(jù)。代碼如下:
import { MyContext } from './myContext' class ContextDemo extends React.Component<{}> { ????render() { ????????return ( ????????????<MyContext.Provider ????????????????value={someValue} // 放入數(shù)據(jù),它的數(shù)據(jù)類型必須與IMyContext接口兼容 ????????????> ????????????????// children ????????????</GlobalContext.Provider> ????????) ????} }
訂閱 Context
此處是管道的出口,對于 Context 對象而言,管道入口只有一個(gè),但出口可以有多個(gè)。訂閱 Context 有多種方式,總體而言有如下三種:
類組件的靜態(tài)屬性 contextType
只能在類組件中使用,并且只能訂閱一個(gè) Context。用法如下:
class MyNestedClass extends React.Component<{}> { static contextType = MyContext // 訂閱第一步創(chuàng)建的Context render() {/**todo*/} }
在類組件中使用 contextType 訂閱 Context 之后,除了不能在構(gòu)造函數(shù)中使用 this.context 訪問到數(shù)據(jù)之外,在類組件的其他位置都能使用 this.context 訪問到數(shù)據(jù)。生命周期 shouldComponentUpdate 的第三個(gè)參數(shù)是組件即將接收的 context。
useContext
在函數(shù)組件中通過 useContext 訂閱 Context,useContext 的使用次數(shù)不限。用法如下:
function MyNestedFunc() { const myContext = useContext(MyContext) // 訂閱第一步創(chuàng)建的Context return (/**todo*/) }
Context.Consumer
它是組件,在 Context 作用域任何位置都能使用它,它只有一個(gè)名為 children 的 prop,children 必須是一個(gè)返回 React.ReactNode 的函數(shù),該函數(shù)接收當(dāng)前的 context 作為參數(shù),用法如下:
<MyContext.Consumer> {(context) => <MyNestedCom lang={context.lang}/>} </MyContext.Consumer>
Context + useReducer
Context + useReducer 指的是用 useReducer 管理狀態(tài),用 Context 傳遞值。與 Context 基本用法相比需要變化的是第二步,示例代碼如下:
// context要傳遞的數(shù)據(jù)類型 interface IStyleContext { theme: 'light' | 'dark'; size: 's' | 'm' | 'l'; changeTheme: (theme: 'light' | 'dark') => void; changeSize: (size: 's' | 'm' | 'l') => void; } function ProviderCom() { // 用 useReducer 創(chuàng)建狀態(tài) const [style, dispatch] = useReducer(reducer, {theme: 'light', size: 'm'}) // 避免 ContextVal 被頻繁新建 const ContextVal = useMemo<IStyleContext>(() => { return { theme: style.theme, size: style.size, changeSize: (size: IStyleContext['size']) => dispatch({type: 'size', payload: size}), changeTheme: (theme: IStyleContext['theme']) => dispatch({type: 'theme', payload: theme}) } }, [style.size, style.theme]) return ( <StyleContext.Provider value={ContextVal}> // 將要傳遞的數(shù)據(jù)放到 Context 中 {/* todo */} </StyleContext.Provider> ) }
在上述示例中,狀態(tài)由 useReducer 創(chuàng)建,被 reducer 函數(shù)更新,StyleContext 只負(fù)責(zé)傳遞數(shù)據(jù),被 StyleContext.Provider 包裹的組件能訂閱 StyleContext。
總結(jié)
只要 context value 被更新,那么訂閱該 context 的組件一定會(huì)重新渲染,而不管 context value中更新的那部分值是否被它使用,也不管它的祖先組件是否跳過重新渲染,所以推薦將不同職責(zé)的數(shù)據(jù)保存到不同的 context 中,以減少不必要的重新渲染。
如果 Context.Provider 的 value 屬性傳遞了一個(gè)對象字面量,那么 Context.Provider 的父組件每一次重新渲染都會(huì)使 context value 更新,進(jìn)而導(dǎo)致訂閱該 context 的組件重新渲染,所有應(yīng)該避免給 Context.Provider 的 value 傳對象字面量。
以上就是React高級概念之Context用法詳解的詳細(xì)內(nèi)容,更多關(guān)于React Context用法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
ahooks控制時(shí)機(jī)的hook實(shí)現(xiàn)方法
這篇文章主要為大家介紹了ahooks控制時(shí)機(jī)的hook實(shí)現(xiàn)方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07IntersectionObserver實(shí)現(xiàn)加載更多組件demo
這篇文章主要為大家介紹了IntersectionObserver實(shí)現(xiàn)加載更多組件demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07基于React Context實(shí)現(xiàn)一個(gè)簡單的狀態(tài)管理的示例代碼
本文主要介紹了基于React Context實(shí)現(xiàn)一個(gè)簡單的狀態(tài)管理的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07React中異步數(shù)據(jù)更新不及時(shí)問題及解決
這篇文章主要介紹了React中異步數(shù)據(jù)更新不及時(shí)問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03react如何實(shí)現(xiàn)一個(gè)密碼強(qiáng)度檢測器詳解
這篇文章主要給大家介紹了關(guān)于react如何實(shí)現(xiàn)一個(gè)密碼強(qiáng)度檢測器的相關(guān)資料,使用這個(gè)密碼強(qiáng)度器后可以幫助大家提高在線帳號、個(gè)人信息的安全性,需要的朋友可以參考下2021-06-06