我们在这里讨论两个不同的主题:
- 多次导入同一个模块
- 对多次导入的模块使用共享或单独状态(您提到了上下文 API)
1。多次导入同一个模块
在多个其他模块中导入相同的模块是完全可以的。想想我们在每个文件中都导入了React。
这是关于这个主题的一个很好的答案:ES6 import duplicates
另外,下面我添加一个包含嵌套结构的示例
(B 和 C 都导入 D,A 导入 B 和 C)。
这里D从B和C向上传递到A,因此可以在A内部比较两个导入,并且如您所见,D是相同的,
(控制台输出:D_from_B === D_from_C: true):
// -- ComponentD.jsx --
import React from 'react';
export default function ComponentD(props){
return (<span>imported module ComponentD</span>);
};
// == ComponentC.jsx ==
import React, { useEffect } from 'react';
import ComponentD from './ComponentD';
export default function ComponentC( props ){
useEffect(()=>{ props.passSub( ComponentD ); },[]);
return (<div>
<p>ComponentC</p>
<ComponentD />
</div>);
};
// == ComponentB.jsx ==
import React, { useEffect } from 'react';
import ComponentD from './ComponentD';
export const ComponentB = (props)=>{
useEffect(()=>{ props.passSub( ComponentD ); });
return (<div>
<p>ComponentB</p>
<ComponentD />
</div>);
};
// == ComponentA.jsx ==
import React, { useEffect } from 'react';
import { ComponentB } from './ComponentB';
import ComponentC from './ComponentC';
let componentDfromB = null;
let componentDfromC = null;
export const ComponentA = (props)=>{
useEffect(()=>{
console.log('D from B === D from C:', componentDfromB === componentDfromC); // <--- true
console.log('Object.is(DB, DC):', Object.is(componentDfromB, componentDfromC)); // <--- true
});
return (<div>
<ComponentB passSub={ function( Sub ){ componentDfromB = Sub; } } />
<ComponentC passSub={ function( Sub ){ componentDfromC = Sub; } } />
</div>);
};
备注:此代码仅用于说明这一点。这种方法在普通 App 中通常无法正常工作(例如,在回调中设置 componentDfromB。)
2。使用共享或个人状态
所以,导入的模块是相同的。但状态不是。
导入的“事物”是 React.Component,而不是 React.Element,类似于关系 class vs. 实例。
如果 React.Component D 被导入,它会在导入它的组件内部实例化,因此每个导入组件(B 和 C)都有其自己的实例 D,具有单独的、自己的状态。但这通常正是您想要的。
如果你想在不同的组件之间共享相同的状态,你会使用上下文、redux、传递道具等技术……我认为细节超出了这个问题的范围。
那么性能呢……
我想说性能在这里没有问题,与模块导入无关,与状态无关。
我认为没有人真的会出于性能原因选择此处讨论的方法,而是出于数据结构或代码清洁度的考虑(当然,糟糕的数据结构可能会有糟糕的性能,但这不是 React 的“错误” -状态)。
如果您仍然对性能感到好奇,我认为这应该是一个单独的、更具体的问题,例如“性能状态与道具”之类的问题。