динамически импортировать компонент React, если этот файл существует, в противном случае показать сообщение по умолчанию - PullRequest
0 голосов
/ 15 ноября 2018

Я хочу условно импортировать React Component, если файл существует и, если нет, сделать что-то еще. Например, показать представление по умолчанию или сообщение.

Я пробовал это:

let Recipe;
try {
  Recipe = require(`docs/app/Recipes/${props.componentName}`);
} catch (e) {
  Recipe = () => <div>Not found</div>;
}

Однако Линтер жалуется, что я не должен пытаться динамически запрашивать файл, а вместо этого использовать строковый литерал.

Есть ли более чистый подход к тому, чего я пытаюсь достичь?

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Проблема в том, что этот подход убивает оптимизацию пакета и включает все файлы из docs/app/Recipes/ в пакет, даже если они не используются.

Лучший способ написать это - использовать <React.Suspense> и React.lazy:

const Recipe = React.lazy(() =>
  import(`docs/app/Recipes/${props.componentName}`)
  .catch(() => ({ default: () => <div>Not found</div> }))
);

Что используется как:

<React.Suspense fallback={'loading...'}><Recipe/></React.Suspense>

Более чистый способ сделать это и избежать ошибки линтера - создать карту возможных компонентов:

import Foo from 'docs/app/Recipes/Foo';
import Bar from 'docs/app/Recipes/Bar';
...

const componentsMap = { Foo, Bar };

...

const Recipe = componentsMap[props.componentName] || () => <div>Not found</div>;

В этом случае props.componentName может быть проверено при необходимости.

0 голосов
/ 15 ноября 2018

на самом деле есть.С недавним выпуском React v16.6.0 " lazy code spliting " был представлен.Вот как это работает, имеет смысл использовать его вместе с реакцией «ожидание»:

 import React, {lazy, Suspense} from 'react';
 const Recipe = lazy(() =>import(`./docs/app/Recipes/${props.componentName}`));

    function SomeComponent() {
      return (
        <Suspense fallback={<Spinner/>}>
          <Recipe />
        </Suspense>
      );
    }

Чтобы справиться с ситуацией, когда компонент не найден, вы можете использовать Границы ошибок .Вы бы обернули свой компонент этим следующим образом:

<ErrorBoundary>
  <Suspense fallback={<Spinner/>}>
    <Recipe />
  </Suspense>
</ErrorBoundary>

Лучше всего, вы читаете об этом больше непосредственно в документах о реагировании, которые я связал выше.

...