Реагируйте динамически, используя подкомпоненты с реквизитом

Возможно, есть лучший способ, но я стараюсь сделать свои компоненты React максимально пригодными для повторного использования. Итак, я использую загрузочную карту, и внутри этой карты я хочу динамически размещать различные компоненты снаружи (с реквизитами). Без реквизита работает нормально. Но с реквизитами я получил сообщение об ошибке «Ошибка: не удается найти модуль«../../pages/Dummy»».

Это работает идеально:

import React, {Suspense} from 'react';
import { MDBCard, MDBCardBody } from "mdbreact";

const Area = (props) => {

    const OtherComponent = React.lazy(() => import('../../pages/Dummy'));

    return (
            <MDBCard className="text-center">
                <MDBCardBody>
                    <Suspense fallback={<div>Loading...</div>}>
                        <OtherComponent/>
                    </Suspense>
                </MDBCardBody>
            </MDBCard>
    );
};

export default Area;

Это не работает:

import React, {Suspense} from 'react';
import { MDBCard, MDBCardBody } from "mdbreact";

const Area = (props) => {

    const OtherComponent = React.lazy(() => import(props.compName));

    return (
            <MDBCard className="text-center">
                <MDBCardBody>
                    <Suspense fallback={<div>Loading...</div>}>
                        <OtherComponent/>
                    </Suspense>
                </MDBCardBody>
            </MDBCard>
    );
};

export default Area;

Звонок извне:

<Area compName='../../pages/Dummy'/>

Как будто я не могу лениво загружать реквизит. Очень странный.

Кстати. Мне не нужно использовать ленивую загрузку, если есть более простой способ динамического использования подкомпонентов. Я просто думал, что это единственный способ.


person Andrew    schedule 24.11.2019    source источник


Ответы (1)


Есть несколько вариантов:

В первом используются «слоты», о которых вы можете прочитать в документации React здесь. или статью здесь.

const DummyOne = React.lazy(() => import('../../pages/DummyOne');
const DummyTwo = React.lazy(() => import('../../pages/DummyTwo');

const Area = ({ comp }) => {
  return (
    <MDBCard className="text-center">
      <MDBCardBody>
        <Suspense fallback={<div>Loading...</div>}>
          {comp}
        </Suspense>
      </MDBCardBody>
    </MDBCard>
  );
}

// You dynamically pass the component itself into 'Area'
<Area comp={<DummyOne />} />

Второй вариант ближе к тому, что у вас есть:

const Area = ({ compName }) => {
  const components = {
    DummyOne: React.lazy(() => import('../../pages/DummyOne'),
    DummyTwo: React.lazy(() => import('../../pages/DummyTwo'),
  }

  const DynamicComponent = components[compName];

  return (
    <MDBCard className="text-center">
      <MDBCardBody>
        <Suspense fallback={<div>Loading...</div>}>
          <DynamicComponent />
        </Suspense>
      </MDBCardBody>
    </MDBCard>
  );
}

// You dynamically pass the component name to 'Area' as a string
<Area compName="DummyOne" />
person helloitsjoe    schedule 24.11.2019