摘要:我們只希望最多有兩個并發渲染器主要和次要主要和次要。輔助渲染器將自己的的存儲在多帶帶的字段中。
前言:
由于childContext在React17中會被廢棄,所以不去分析它了,主要是新 API— —createContext()的講解
一、React.createContext()
作用:
方便祖先組件與后代組件(中間隔了好多層組件)傳值
使用:
context.js:
import React from "react"; const contextTestOne={ name:"chen", length:22, } export const wrapContext=React.createContext(contextTestOne.name)
祖先組件:
import { wrapContext } from "@/utils/context"; const Father=props=>{ return () }
子孫組件:
import { wrapContext } from "@/utils/context"; const getProviderValue=()=>{ return{value=>{value}} } const Child=props=>{ return ( getProviderValue() ); }
結果:
注意:
將undefined傳遞給
React 官方文檔:
https://zh-hans.reactjs.org/docs/context.html#contextprovider
源碼:
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ import {REACT_PROVIDER_TYPE, REACT_CONTEXT_TYPE} from "shared/ReactSymbols"; import type {ReactContext} from "shared/ReactTypes"; import warningWithoutStack from "shared/warningWithoutStack"; import warning from "shared/warning"; export function createContext( defaultValue: T, //使用Object.is()計算新老context的差異 calculateChangedBits: ?(a: T, b: T) => number, ): ReactContext { if (calculateChangedBits === undefined) { calculateChangedBits = null; } else { //不看 if (__DEV__) { warningWithoutStack( calculateChangedBits === null || typeof calculateChangedBits === "function", "createContext: Expected the optional second argument to be a " + "function. Instead received: %s", calculateChangedBits, ); } } const context: ReactContext = { //還是那句話,ReactContext中的$$typeof是 // 作為createElement中的屬性type中的對象進行存儲的,并不是ReactElement的$$typeof $$typeof: REACT_CONTEXT_TYPE, _calculateChangedBits: calculateChangedBits, //作為支持多個并發渲染器的解決方法,我們將一些渲染器分類為主要渲染器,將其他渲染器分類為輔助渲染器。 // As a workaround to support multiple concurrent renderers, we categorize // some renderers as primary and others as secondary. //我們只希望最多有兩個并發渲染器:React Native(主要)和Fabric(次要); // React DOM(主要)和React ART(次要)。 // 輔助渲染器將自己的context的value存儲在多帶帶的字段中。 // We only expect // there to be two concurrent renderers at most: React Native (primary) and // Fabric (secondary); React DOM (primary) and React ART (secondary). // Secondary renderers store their context values on separate fields. // 中的value就是賦值給_currentValue的 //也就是說_currentValue和_currentValue2作用是一樣的,只是分別給主渲染器和輔助渲染器使用 _currentValue: defaultValue, _currentValue2: defaultValue, // Used to track how many concurrent renderers this context currently // supports within in a single renderer. Such as parallel server rendering. //用來追蹤該context的并發渲染器的數量 _threadCount: 0, // These are circular Provider: (null: any), Consumer: (null: any), }; //const obj={} //obj.provider._obj = obj context.Provider = { $$typeof: REACT_PROVIDER_TYPE, _context: context, }; let hasWarnedAboutUsingNestedContextConsumers = false; let hasWarnedAboutUsingConsumerProvider = false; //不看 if (__DEV__) { // A separate object, but proxies back to the original context object for // backwards compatibility. It has a different $$typeof, so we can properly // warn for the incorrect usage of Context as a Consumer. const Consumer = { $$typeof: REACT_CONTEXT_TYPE, _context: context, _calculateChangedBits: context._calculateChangedBits, }; // $FlowFixMe: Flow complains about not setting a value, which is intentional here Object.defineProperties(Consumer, { Provider: { get() { if (!hasWarnedAboutUsingConsumerProvider) { hasWarnedAboutUsingConsumerProvider = true; warning( false, "Rendering is not supported and will be removed in " + "a future major release. Did you mean to render instead?", ); } return context.Provider; }, set(_Provider) { context.Provider = _Provider; }, }, _currentValue: { get() { return context._currentValue; }, set(_currentValue) { context._currentValue = _currentValue; }, }, _currentValue2: { get() { return context._currentValue2; }, set(_currentValue2) { context._currentValue2 = _currentValue2; }, }, _threadCount: { get() { return context._threadCount; }, set(_threadCount) { context._threadCount = _threadCount; }, }, Consumer: { get() { if (!hasWarnedAboutUsingNestedContextConsumers) { hasWarnedAboutUsingNestedContextConsumers = true; warning( false, "Rendering is not supported and will be removed in " + "a future major release. Did you mean to render instead?", ); } return context.Consumer; }, }, }); // $FlowFixMe: Flow complains about missing properties because it doesn"t understand defineProperty context.Consumer = Consumer; } else { //const obj={} //obj.consumer=obj //也就是Consumber對象指向React.Context對象 //在 進行渲染時,為了保證Consumer拿到最新的值, //直接讓Consumer=React.Context, // React.Context中的_currentValue已經被 的value給賦值了 //所以Consumer能立即拿到最新的值 context.Consumer = context; } //不看 if (__DEV__) { context._currentRenderer = null; context._currentRenderer2 = null; } return context; }
解析:
不看__DEV__的話,還是挺簡單的,需要注意的是context.Consumer = context,讓
二、為什么要棄用childContext?
因為childContext對下層的組件影響太大了,即使子孫組件沒有用到childContext,子孫組件仍然要進行Update,嚴重影響了性能
(完)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106160.html
摘要:接收一個屬性,這個組件會讓后代組件統一提供這個變量值。因此對于同一個對象而言,一定是后代元素。解決方法就是把內聯函數提取出來,如下講了這么多,我們還沒有講到其實我們已經講完了的工作原理了。 本節主要講解以下幾個新的特性: Context ContextType lazy Suspense 錯誤邊界(Error boundaries) memo 想閱讀更多優質文章請猛戳GitHub博...
摘要:官方對的介紹是意思就是提供了一種通過組件樹傳遞數據的方法,而無需在每個級別手動傳遞。這也是基于重要物證哈哈實例使用學習技術最終是要有產出的。依然被視作一個組件,不過不同的是它的子組件必須是一個方法并且該方法接收當前對象并最終返回一個節點。 拋轉引玉 通過上一篇的科普我們知道如果父節點需要向子節點傳遞數據,那么就得通過Props來實現;那么擺在我們眼前的就有一個問題了:現有N個節點并且它...
摘要:到主菜了,先看它的一看,我們應該有個猜測,這貨是個高階函數。可能有點繞,但就是這么一個個高階函數組成的,后面會詳細說。定義了一個處理函數和高階函數執行次的方法,這個方法比上面的復雜在于它需要檢測參數是否訂閱了。 注意:文章很長,只想了解邏輯而不深入的,可以直接跳到總結部分。 初識 首先,從它暴露對外的API開始 ReactReduxContext /* 提供了 React.creat...
摘要:引言于發布版本,時至今日已更新到,且引入了大量的令人振奮的新特性,本文章將帶領大家根據更新的時間脈絡了解的新特性。其作用是根據傳遞的來更新。新增等指針事件。 1 引言 于 2017.09.26 Facebook 發布 React v16.0 版本,時至今日已更新到 React v16.6,且引入了大量的令人振奮的新特性,本文章將帶領大家根據 React 更新的時間脈絡了解 React1...
摘要:第一次了解這項特性的時候,真的有一種豁然開朗,發現新大陸的感覺。在絕大多數情況下,是更好的選擇。唯一例外的就是需要根據新的來進行操作的場景。會保證在頁面渲染前執行,也就是說頁面渲染出來的是最終的效果。上面條規則都是為了保證調用順序的穩定性。 歡迎關注我的公眾號睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、...
閱讀 1684·2021-09-26 09:55
閱讀 3713·2021-09-22 15:31
閱讀 7328·2021-09-22 15:12
閱讀 2209·2021-09-22 10:02
閱讀 4625·2021-09-04 16:40
閱讀 1031·2019-08-30 15:55
閱讀 3018·2019-08-30 12:56
閱讀 1813·2019-08-30 12:44