【问题标题】:React - finding a proper way to use a common component amongst multiple parent componentsReact - 找到在多个父组件中使用公共组件的正确方法
【发布时间】:2021-01-20 09:25:29
【问题描述】:

我仍在弄清楚 React 是如何工作并渲染其组件的,并且已经有一段时间了这个问题 - 假设我有一个组件 D 被导入到组件 B 和 C 中,并且 B 和 C 都被导入到组件中A. 所以组件树如下所示:

组件 A

  • 组分 B
    • 组件 D
  • 组分 C
    • 组件 D

似乎组件 D 通过组件 B 和 C 被两次导入到组件 A 中(尽管是间接的)。我想知道这是否会产生性能问题,以及我是否应该尝试确保组件 D 仅从组件 A 中包含一次透视图(我猜使用 Context API 可以解决这个问题?)

【问题讨论】:

  • 您可以将 is 导入到组件 A,并将其作为 prop 传递给组件 B 和 C。
  • 是的,这可能是个问题,这就是为什么你可以使用 redux 来解决这个问题。您可以检查以下答案。 stackoverflow.com/questions/65785994/…
  • 我认为 webpack 的工作方式不会成为问题。您可以检查您的构建文件以查看是否获得了组件 D 的两个副本。我认为 webpack 会将组件 D 保存为变量,然后在需要时访问该变量。不过我可能是错的。

标签: javascript reactjs frontend


【解决方案1】:

我们在这里讨论两个不同的主题:

  1. 多次导入同一个模块
  2. 对多次导入的模块使用共享或单独状态(您提到了上下文 API)

1。多次导入同一个模块

在多个其他模块中导入相同的模块是完全可以的。想想我们在每个文件中都导入了React

这是关于这个主题的一个很好的答案:ES6 import duplicates

另外,下面我添加一个包含嵌套结构的示例
BC 都导入 DA 导入 BC)。

这里DBC向上传递到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 被导入,它会在导入它的组件内部实例化,因此每个导入组件(BC)都有其自己的实例 D,具有单独的、自己的状态。但这通常正是您想要的。

如果你想在不同的组件之间共享相同的状态,你会使用上下文、redux、传递道具等技术……我认为细节超出了这个问题的范围。

那么性能呢……

我想说性能在这里没有问题,与模块导入无关,与状态无关。

我认为没有人真的会出于性能原因选择此处讨论的方法,而是出于数据结构或代码清洁度的考虑(当然,糟糕的数据结构可能会有糟糕的性能,但这不是 React 的“错误” -状态)。

如果您仍然对性能感到好奇,我认为这应该是一个单独的、更具体的问题,例如“性能状态与道具”之类的问题。

【讨论】:

    猜你喜欢
    • 2021-01-29
    • 2022-01-12
    • 2019-04-14
    • 2019-08-05
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多