React?數(shù)據(jù)共享useContext的實(shí)現(xiàn)
因?yàn)橐咔椋?最近接手一個(gè)新項(xiàng)目。是React的。上次寫(xiě)React已經(jīng)過(guò)去1年多了。
雖然撿起來(lái)也不是什么難事,不過(guò)技術(shù)這個(gè)東西,長(zhǎng)時(shí)間不用就容易忘記。
為了保證這個(gè)項(xiàng)目根其他平行項(xiàng)目的技術(shù)棧統(tǒng)一。
采用的是 Nextjs 、styled-components、useContext 、react-query、ts
今天不做重點(diǎn)介紹項(xiàng)目,還是說(shuō)說(shuō)在項(xiàng)目中碰到的問(wèn)題。
這個(gè)足足折騰了差不多2個(gè)小時(shí),我一直在排查其問(wèn)題。
最后這個(gè)問(wèn)題也是比較的詭異。
ReferenceError: Cannot access 'Context' before initialization This error happened while generating the page. Any console logs will be displayed in the terminal window.
引用錯(cuò)誤 , 不能在初始化之前訪問(wèn)Context
, 在生成頁(yè)面的時(shí)候就已經(jīng)發(fā)生。在Shell控制臺(tái)也有顯示輸出。
我嘗試過(guò)很多的辦法, 例如:換用引用的方式、多個(gè)Provider
的位置調(diào)整,甚至只保留一個(gè) , 依然無(wú)法解決。
后來(lái)我試試可能組建聲明的類(lèi)型問(wèn)題。
我平時(shí)對(duì)于寫(xiě)組建的方式比較隨意。
最喜歡的一種方式就是
import { useState , createContext} from 'react' import Me from './me' export const MyContext = createContext({}); export default function Demo(){ const [say , setSay] = useState(''); return ( <MyContext.Provider value={{say , setSay}}> <div>father</div>誰(shuí)在講話 {say} <Me /> </FatherContext.Provider> ) }
React.FC是函數(shù)式組件寫(xiě)法,是在TypeScript使用的一個(gè)泛型,F(xiàn)C就是FunctionComponent的縮寫(xiě),事實(shí)上React.FC可以寫(xiě)成React.FunctionComponent ( 我對(duì)這種寫(xiě)法感覺(jué)太過(guò)于冗余 )
import React, { createContext, FunctionComponent, useState } from 'react' import Me from './me' interface DemoProps { say: string; setSay: React.Dispatch<React.SetStateAction<boolean>>; demoString?:string; } const defaultDemoProps: DemoProps = { isDay: true, setIsDay: (day) => day }; export const MyContext = createContext<DemoProps>({...defaultDemoProps}); const Demo: React.FC<DemoProps> = ({ children, ...props }) => { const { say : propIsSay } = props; const [ isSay, setSay ] = useState(propIsDay) return <MyContext.Provider value={{ say,setSay}}> <Me /> </MyContext.Provider> } export default Demo;
還有很多習(xí)慣使用class components
import React, { createContext, PureComponent } from 'react' import Me from './me' export const MyContext = createContext({}) export default class Demo extends PureComponent { state = { say:true, } setSay ()=>{ let say = !this.state.say this.setState({ say }); } render() { return( <MyContext.Provider value={{ say,setSay}}> <Me /> <MyContext.Provider> ) } }
這是三種的構(gòu)造方式
createContext 函數(shù)返回的有3個(gè)屬性分別是 Provider ( 提供者 )、Customer( 消費(fèi)者 )、displayName ( 貌似用不到 )
import React, { Context, PureComponent } from 'react'; import {MyContext} from '../components/data'; import Memo from '../components/classDemo'; export const MyContext = React.createContext() export default class CurstomerDemo extends PureComponent { static contextType = MyContext // 重點(diǎn)是這句 用來(lái)指定 constructor(props) { super(props); } handleClick = () => { console.log (this.context) // 獲取上下文 Provider 屬性 } render() { return ( <div> <button>Provider</button> <button onClick={this.handleClick}>Customer</button> </div> ) } } import React, { useState ,useContext, createContext} from 'react' import {MyContext} from './Demo' function useCountContext(CounterContext) { const context = useContext(MyContext) //重點(diǎn)這句話,用來(lái)獲取指定的上線文Context if (!context) { throw new Error('useCountContext must used within Context.Provider') } return context } export default function Me(props){ let context = useCountContext(MyContext) let {say , setSay} = context return ( <div> me <button onClick={()=>{ setSay(say + ',同志們好') }}>come from grandpa Provier {say}</button> </div> ) }
其實(shí)關(guān)鍵的還是用函數(shù)方式來(lái)接受函數(shù)的Provider , 類(lèi)組件來(lái)接受類(lèi)組件的Provider。保證構(gòu)造的一致。
PS:useContext
我個(gè)人覺(jué)得對(duì)于小型項(xiàng)目還是非常的不錯(cuò),但是對(duì)于復(fù)雜的數(shù)據(jù),他的分層意識(shí)還是不夠清晰。thunk
、saga
、mobx
都在一定程度上在分層上更適合context
。當(dāng)然你也可以對(duì)context
更進(jìn)一步封裝。適合自己的才是最好!
到此這篇關(guān)于React 數(shù)據(jù)共享useContext的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)React 數(shù)據(jù)共享useContext內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React組件中監(jiān)聽(tīng)函數(shù)獲取不到最新的state問(wèn)題
這篇文章主要介紹了React組件中監(jiān)聽(tīng)函數(shù)獲取不到最新的state問(wèn)題問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01react自定義實(shí)現(xiàn)狀態(tài)管理詳解
這篇文章主要為大家詳細(xì)介紹了react如何自定義實(shí)現(xiàn)狀態(tài)管理,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01React-router 4 按需加載的實(shí)現(xiàn)方式及原理詳解
本篇文章主要介紹了React-router 4 按需加載的實(shí)現(xiàn)方式及原理詳解,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05react用Redux中央倉(cāng)庫(kù)實(shí)現(xiàn)一個(gè)todolist
這篇文章主要為大家詳細(xì)介紹了react用Redux中央倉(cāng)庫(kù)實(shí)現(xiàn)一個(gè)todolist,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09解析react?函數(shù)組件輸入卡頓問(wèn)題?usecallback?react.memo
useMemo是一個(gè)react hook,我們可以使用它在組件中包裝函數(shù)??梢允褂盟鼇?lái)確保該函數(shù)中的值僅在依賴(lài)項(xiàng)之一發(fā)生變化時(shí)才重新計(jì)算,這篇文章主要介紹了react?函數(shù)組件輸入卡頓問(wèn)題?usecallback?react.memo,需要的朋友可以參考下2022-07-07