自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

React:不要?jiǎng)?,否則你會(huì)被炒魷魚

開發(fā) 前端
本文我們介紹react與react-dom?中神秘的內(nèi)部變量__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED的作用。

大家好,我卡頌。

不知道大家在用React開發(fā)時(shí),有沒有注意到react與react-dom這兩個(gè)包中有個(gè)很奇葩的屬性__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:

圖片

直譯過來就是「內(nèi)部神秘屬性,不要亂用!否則你會(huì)被炒魷魚」。

為什么會(huì)有個(gè)這么唬人的屬性?今天我們來聊聊。

React項(xiàng)目架構(gòu)

我們在項(xiàng)目中習(xí)慣使用如下語句引入Hook:

import {useState} from 'react';

這是不是意味著所有Hook?的具體實(shí)現(xiàn)都在react這個(gè)包中?實(shí)際不是的。

所有Hook?的具體實(shí)現(xiàn)在ReactFiberHooks.new.js?方法中,該方法來自于react-reconciler這個(gè)包。

那為什么我們項(xiàng)目中從來沒有主動(dòng)引入過這個(gè)包呢?因?yàn)閞eact-reconciler?中被使用的部分,被打包進(jìn)react-dom中了。

簡單來說,React為了實(shí)現(xiàn)跨平臺(tái)渲染,采用的是「一個(gè)主模塊」 + 「一個(gè)渲染器」的模式。

其中「主模塊」就是react包,他提供了所有通用方法。

「渲染器」針對宿主環(huán)境不同而不同,比如:

  • 瀏覽器環(huán)境使用ReactDOM/client渲染器。
  • SSR使用ReactDOM/server渲染器。
  • Native環(huán)境使用ReactNative渲染器。

渲染器除了「宿主環(huán)境相關(guān)的代碼」外,還有大量通用邏輯(比如Diff算法)。

所以可以認(rèn)為,react-dom是由如下多個(gè)包中「被使用的部分」打包而成:

  • shared,一個(gè)存放通用方法的包。
  • react-reconciler,提供包括Hooks的實(shí)現(xiàn)、Diff算法、優(yōu)先級調(diào)度等更新相關(guān)功能。
  • react-dom,提供宿主環(huán)境方法,比如「DOM的增/移動(dòng)/刪/改」。
  • 等等其他包。

這也是為什么宿主環(huán)境千差萬別,但都能通過執(zhí)行useState改變狀態(tài),觸發(fā)視圖更新。

原因在于 —— 「Hooks的實(shí)現(xiàn)」與「宿主環(huán)境操作視圖的方法」被打包進(jìn)了同一個(gè)包中。

既然「Hooks的實(shí)現(xiàn)」被打包進(jìn)react-dom?(或其他宿主環(huán)境對應(yīng)的包)中,那如何做到最終使用時(shí)是從react中導(dǎo)出的呢?就像這樣:

// 而不是 from 'react-dom'
import {useState} from 'react';

這就用到了開篇提到的變量__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED。

內(nèi)部結(jié)構(gòu)

可以認(rèn)為,當(dāng)React?團(tuán)隊(duì)希望在react與「宿主環(huán)境對應(yīng)的包」之間共享數(shù)據(jù)時(shí),就會(huì)把他保存在這個(gè)神秘的內(nèi)部變量中。

比如上文提到的,「Hook的具體實(shí)現(xiàn)」。

再比如,object.assign?方法的polyfill?,在react?與react-dom?中都會(huì)用到,但如果兩個(gè)包中分別引入,再分別打包,那么polyfill?的代碼會(huì)重復(fù)出現(xiàn)在react?與react-dom兩個(gè)包中。

為了減少重復(fù)代碼,react?會(huì)引入object.assign?方法的polyfill,再將它保存在神秘的內(nèi)部變量中。

react?作為react-dom的peerDependencies?,當(dāng)項(xiàng)目中引入這兩個(gè)包后,react-dom?內(nèi)部使用的object.assign?實(shí)際來自react:

// react-dom包內(nèi)部
const react = require('react');
const { assign } = react.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;

常見問題

了解了神秘的內(nèi)部變量的作用,我們再來看看這種實(shí)現(xiàn)會(huì)造成的問題。

假設(shè)我們有2個(gè)項(xiàng)目:

  • 組件庫項(xiàng)目A,負(fù)責(zé)開發(fā)組件。
  • 業(yè)務(wù)項(xiàng)目B,依賴A。

B安裝依賴后,A會(huì)出現(xiàn)在B的node_modules中。

為了調(diào)試方便,我們用npm link功能將B中依賴的A由「B的node_modules中的A」改為「組件庫項(xiàng)目A」,

當(dāng)npm link?后,B中業(yè)務(wù)代碼使用的useState來自于「B的node_modules中的react」。

而B中引入的組件庫A的組件中使用的useState來自于「A的node_modules中的react」。

不同的react?對應(yīng)不同的__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?,最終對應(yīng)不同的react-dom。

這就會(huì)造成報(bào)錯(cuò)。

解決辦法是在項(xiàng)目中為react?增加別名(alias),使項(xiàng)目中所有用到react?的地方都指向同一個(gè)react。

總結(jié)

本文我們了解了react與react-dom?中神秘的內(nèi)部變量__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED的作用。

他能夠在這兩個(gè)包之間傳遞共享的數(shù)據(jù)。

需要注意的一點(diǎn)是,如果你也想用這種方式在兩個(gè)包之間共享數(shù)據(jù),需要將其中一個(gè)包設(shè)為另一個(gè)包的peerDependencies。

否則,在打包時(shí),「被共享的數(shù)據(jù)」只會(huì)在兩個(gè)包中分別存在一份。

責(zé)任編輯:姜華 來源: 魔術(shù)師卡頌
相關(guān)推薦

2023-06-02 06:55:04

2023-02-26 21:42:01

Spring項(xiàng)目配置

2018-07-20 09:24:37

人工智能創(chuàng)業(yè)人才

2010-04-26 10:48:20

喬布斯

2022-06-05 21:27:40

Reacteffect

2022-06-15 22:33:07

React逃生艙

2020-02-26 16:46:49

iPhone電池應(yīng)用程序

2021-11-04 05:44:23

魷魚游戲加密貨幣騙局

2022-05-20 15:27:41

React工具Vue

2009-12-04 10:04:58

企業(yè)安全盜秘

2015-09-01 10:29:44

數(shù)據(jù)安全

2023-04-11 16:31:10

開發(fā)React 庫Web

2015-10-15 09:39:06

2010-11-09 10:36:39

求職

2021-12-28 00:26:44

Windows微軟應(yīng)用

2013-03-08 09:54:25

2021-05-08 17:18:12

iPhone手機(jī)iOS

2021-06-21 15:49:39

React動(dòng)效組件

2011-10-18 13:43:31

福布斯信息技術(shù)企業(yè)計(jì)算

2012-05-24 10:29:54

編程程序員
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)