初探React Context API

    最近在整理CSS自定義屬性在React中的使用時(shí)了解到“可以使用React Context API相關(guān)的知識(shí)更好的在React組件中使用CSS自定義屬性”,但是自己對(duì)這方面的知識(shí)了解的并不多,因此想借此機(jī)會(huì)來學(xué)習(xí)React Context API相關(guān)的知識(shí)。愛掏網(wǎng) - it200.com也基于這個(gè)原因有了這篇文章。愛掏網(wǎng) - it200.com

    我們從一個(gè)React的實(shí)例開始。愛掏網(wǎng) - it200.com假設(shè)你要構(gòu)建一個(gè)React的應(yīng)用,該應(yīng)用有一個(gè)最簡(jiǎn)單的功能,就是Dark Mode的切換。愛掏網(wǎng) - it200.com簡(jiǎn)單地說,在Web應(yīng)用上一個(gè)切換組件(比如ThemeToggle),用戶點(diǎn)擊該切換按鈕可以讓頁(yè)面在暗色系(dark)和亮色系(light)之間切換。愛掏網(wǎng) - it200.com

    通常我們會(huì)通過props為所有組件提供當(dāng)前主題的模式,并使用state來更新當(dāng)前的主題。愛掏網(wǎng) - it200.com

    /src/components/目錄下分別創(chuàng)建了GrandChild、Child、ParentComponentThemeToggle幾個(gè)組件:

    示例代碼如下:

    // /src/components/GrandChild
    import React from 'react'
    
    const GrandChild = (props) => {
        const styled = {
            color: `${props.theme.color}`,
            background: `${props.theme.background}`
        }
        return 

    Theme Toggle

    } export default GrandChild; // /src/components/Child import React from 'react' import GrandChild from '../GrandChild' const Child = (props) => { const styled = { border: `5px solid ${props.theme.color}`, padding: `10vmin 20vmin`, borderRadius: '8px' } return } export default Child // /src/components/ParentComponent import React from 'react' import Child from '../Child' const ParentComponent = (props) => export default ParentComponent // /src/components/ThemeToggle import React from 'react' const ThemeToggle = (props) => { const styled = { background: `${props.theme.background}`, color: `${props.theme.color}`, border: `4px solid currentColor`, borderRadius: `6px`, padding: `2vmin 4vmin`, margin: `4vmin`, cursor: `pointer` } return } export default ThemeToggle // /src/App.js import React, {Fragment} from 'react'; import ParentComponent from './components/ParentComponent' import ThemeToggle from './components/ThemeToggle' const dark = { background: '#121212', color: '#fff' } const light = { background: '#fff', color: '#444' } const App = () => { const [theme, setTheme] = React.useState('light') const onClickHander = () => { theme === 'light' ? setTheme('dark') : setTheme('light') } return } export default App;

    效果如下:

    在這個(gè)示例中,在ParentComponent組件中指定了theme這個(gè)props,并且將這個(gè)props一級(jí)一級(jí)往下傳,傳給組件樹下的所有組件。愛掏網(wǎng) - it200.com即,將theme傳遞到需要它的地方,在本例中會(huì)傳到GrandChild組件。愛掏網(wǎng) - it200.comChild組件和themeprops)沒有任何關(guān)系,它只是作為一個(gè)媒體而以。愛掏網(wǎng) - it200.com

    試想一下,在React中組件樹就有點(diǎn)類似于我們熟悉的DOM樹:

    正如上圖所示,我們可以在最底層組件中添加state,但如果要將數(shù)據(jù)傳遞給兄弟組件的話,在React Context API之前,我們只能將state放到他們的父組件中(組件樹中更高的組件位置),然后通過props將其傳遞回同級(jí)組件:

    就像上面的示例,我們需要將state從組件樹的最頂層一級(jí)一級(jí)往下傳,哪怕是所有中間層組件不需要使用這些數(shù)據(jù),但它必須為了后面的組件做為媒介,將state傳遞到最底層組件。愛掏網(wǎng) - it200.com

    對(duì)應(yīng)到上面的示例中,那就是:

    React Context API正是用來解決Prop Drilling的問題。愛掏網(wǎng) - it200.comReact Context API提供了一種通過ProviderConsumer用來提供數(shù)據(jù)和消費(fèi)數(shù)據(jù),它們可以在組件件中傳遞數(shù)據(jù),最主要的是不必要一級(jí)一級(jí)的通過props向組件樹傳遞state。愛掏網(wǎng) - it200.com簡(jiǎn)單地說,在組件樹最頂層的組件中通過Provider提供數(shù)據(jù),在后面的任何一個(gè)子組件樹可以通過Consumer來消費(fèi)Provider提供的數(shù)據(jù):

    React的官網(wǎng)是這樣描述Context的:

    在這個(gè)特性還沒出現(xiàn)之前,在React應(yīng)用中數(shù)據(jù)的通訊是通過props屬性自上而下(由父及子)進(jìn)行傳遞的,換句話說,必須通過props傳遞到每個(gè)組件中,然后在組件中重復(fù)相同的過程。愛掏網(wǎng) - it200.com但這種做法對(duì)于某些類型的屬性而言是極其繁鎖的,也會(huì)變得非常的糟糕,最終可能會(huì)導(dǎo)致props在我們的組件中要不斷的一層一層嵌套。愛掏網(wǎng) - it200.com

    React Context API的出現(xiàn)主要是為了幫助我們解決這方面的問題,它提供了一種在組件之間共享此類值的方式,而不必顯式地通過組件樹的逐層傳遞props。愛掏網(wǎng) - it200.com也就是說,它允許父組件隱式地將數(shù)據(jù)傳遞給子組件(不管組件樹有多深)。愛掏網(wǎng) - it200.com換句話說,可以將數(shù)據(jù)添加到父組件中,然后任何子組件都可以訪問它。愛掏網(wǎng) - it200.com

    假設(shè)我們有這樣的一個(gè)使用場(chǎng)景,在一個(gè)React應(yīng)用中,我們有App、Container、FormButton四個(gè)組件,它們之間是依次被嵌套:

    App ? Container ? Form ? Buttton
    

    假如我們使用props傳遞就需要一層一層往里傳:

    換成Context,就可以直接獲取最頂層App組件綁定的值:

    對(duì)于像我這樣的初級(jí)使用者而言,要想徹底的了解React Context API,只能從最簡(jiǎn)單的應(yīng)用開始。愛掏網(wǎng) - it200.com為了更好的理解它的使用,我們從最簡(jiǎn)單的示例開始。愛掏網(wǎng) - it200.com

    創(chuàng)建上下文對(duì)象

    在React中使用Context的話,我們首要做的就是創(chuàng)建上下文對(duì)象(Context Object)。愛掏網(wǎng) - it200.com可以使用React上的.createContext()創(chuàng)建一個(gè)Context對(duì)象:

    const DataContext = React.createContext()
    

    嘗試著把這個(gè)Context對(duì)象DataContext在控制臺(tái)上打印出來:

    這個(gè)時(shí)候可以從組件樹中離自身最近的那個(gè)匹配的Prrovider中讀取到當(dāng)前的context值。愛掏網(wǎng) - it200.com

    只有當(dāng)組件所處的樹中沒有匹配到Provider時(shí),其defaultValue參數(shù)才會(huì)生效。愛掏網(wǎng) - it200.com這有助于在不使用Provider包裝組件的情況下對(duì)組件進(jìn)地測(cè)試。愛掏網(wǎng) - it200.com

    另外,createContext()方法提供了ProviderConsumer能力,其中一個(gè)是提供者,另一個(gè)是消費(fèi)者,而且這兩個(gè)屬性都是成對(duì)出現(xiàn)的,即每一個(gè)Provider都會(huì)有對(duì)應(yīng)的一個(gè)Consumer。愛掏網(wǎng) - it200.com

    Provider將作為父組件使用,它持有所有Consumer都可以共享的值。愛掏網(wǎng) - it200.com注意,Consumer只能用于Provider的子組件愛掏網(wǎng) - it200.com

    使用Provider提供數(shù)據(jù)

    上一步,使用React.createContext()創(chuàng)建了一個(gè)名為DataContext的上下文對(duì)象,在其中,我們用一些值(value)初始化一個(gè)狀態(tài)(state),可以使用DataContextProvider接受一個(gè)value屬性,傳遞給子組件消費(fèi)(Consumer

    const App = () => 

    Child Component

    ;

    Providervalue屬性的值可以是字符串、數(shù)字或?qū)ο蟆?b class="xhide">愛掏網(wǎng) - it200.com

    消費(fèi)Provider提供的數(shù)據(jù)

    Provider創(chuàng)建了數(shù)據(jù),其創(chuàng)建的數(shù)據(jù)可以通過context對(duì)象的Consumer屬性給子組件消費(fèi)。愛掏網(wǎng) - it200.com主要有三種方法來消費(fèi)Provider屬性創(chuàng)建的數(shù)據(jù)。愛掏網(wǎng) - it200.com

    使用Consumer組件消費(fèi)數(shù)據(jù)

    創(chuàng)建一個(gè)新組件,并且在該組件中使用DataContextConsumer來消費(fèi)數(shù)據(jù)。愛掏網(wǎng) - it200.com這將返回一個(gè)函數(shù),該函數(shù)允許組件消費(fèi)Provider中設(shè)置的值。愛掏網(wǎng) - it200.com比如:

    const ParagraphChildComponent = () => 
        { value => 

    I'm {value.userName}, {value.age}

    包月會(huì)員查看

    聲明:所有內(nèi)容來自互聯(lián)網(wǎng)搜索結(jié)果,不保證100%準(zhǔn)確性,僅供參考。如若本站內(nèi)容侵犯了原著者的合法權(quán)益,可聯(lián)系我們進(jìn)行處理。
    發(fā)表評(píng)論
    更多 網(wǎng)友評(píng)論0 條評(píng)論)
    暫無評(píng)論

    返回頂部

    主站蜘蛛池模板: 亚洲一区二区三区国产精品| 国产激情无码一区二区三区 | 日韩在线一区二区三区视频| 精品国产一区二区三区久| 国产av熟女一区二区三区| 精品久久久中文字幕一区| 亚洲国产精品第一区二区| 精品一区二区三区无码视频| 中文字幕一区二区三匹| 高清国产AV一区二区三区| 亚洲高清偷拍一区二区三区| 亚洲Av无码国产一区二区| 91视频一区二区三区| 无码人妻AⅤ一区二区三区| 成人午夜视频精品一区| 一区二区视频免费观看| 日韩精品无码人妻一区二区三区 | 日本一区二区不卡在线| 一区二区三区在线视频播放| 日本一区免费电影| 香蕉久久ac一区二区三区| 国产精品无码一区二区在线观| 国产精品分类视频分类一区| 在线视频一区二区三区| 亚洲国产美女福利直播秀一区二区| 日本不卡一区二区视频a| 国产一区二区三区在线看| 日本在线不卡一区| 无码人妻精品一区二区三区在线| 无码人妻AⅤ一区二区三区| 99久久精品国产一区二区成人 | 国产日韩精品一区二区在线观看| 亚洲av永久无码一区二区三区| 亚洲综合av一区二区三区| 性盈盈影院免费视频观看在线一区| 欧洲精品码一区二区三区| 国产免费一区二区三区VR| 精品伦精品一区二区三区视频 | 色窝窝免费一区二区三区 | 国产激情з∠视频一区二区| 人妻无码一区二区三区AV|