Преобразование массива в компонент в React

#javascript #reactjs #ecmascript-6 #react-hooks #react-intl

#javascript #reactjs #ecmascript-6 #реагирующие хуки #react-intl

Вопрос:

В проекте есть массив объектов, используемых для заполнения хлебной крошки:

  export const BREADCRUMBS_LIST = [
   { label: 'Home', path: '/', active: false },
   { label: 'Account', path: '/accounts', active: false },
   { label: 'This Account', path: '/accounts', active: true }
 ];
 

он используется для заполнения списка в компоненте Breadcrumbs:

 import { BREADCRUMBS_LIST } from './...'

...

<Breadcrumbs list={BREADCRUMBS_LIST} />
 

Все работает нормально.

Проблема возникает, когда нам нужно перевести эти метки на основе языка пользователя. Для этого мы используем react-intl .

Итак, я преобразовал исходный массив в компонент этой формы:

 import { useIntl } from 'react-intl';

export const BreadcrumbsList = () => {
  const intl = useIntl();

  return [
    { label: intl.formatMessage({ id: 'Home' }), path: '/', active: false },
    {
      label: intl.formatMessage({ id: 'Account' }),
      path: '/accounts',
      active: false
    },
    {
      label: intl.formatMessage({ id: 'This Account' }),
      path: '/accounts',
      active: true
    }
  ];
};
 

и используйте его следующим образом:

 <Breadcrumbs list={BreadcrumbsList} />
 

это кажется неправильным, потому что возвращает сообщение об ошибке:

Не удается прочитать свойство ‘map’ undefined .

В этом компоненте список использовался с map: {list.map(({path, label, active}, index) => {...})

Есть идеи, как решить эту проблему?

Комментарии:

1. Вы передаете ссылку на BreadcrumbList вместо его вызова, поэтому <Breadcrumbs> получит list как экземпляр функции, и map не будет работать с этим.

2. Простое присвоение функции имени в верхнем регистре не означает, что она является компонентом. BreadcrumbsList это всего лишь функция, и вы используете хук внутри функции, которая не рекомендуется командой react. Попробуйте инициализировать перехват вне BreadcrumbsList функции в том месте, где вы его использовали, и просто передайте в intl качестве параметра функции. Кроме того, вы должны вызвать функцию, вы не можете просто передать это как Function . Так что в основном вызывайте его внутри <Breadcrumbs list={BreadcrumbsList()} />

3. Вызов @ BreadcrumbsList() KRTirtho не поможет, это пользовательский хук, который нарушает правила.

4. @DennisVash, если он не использует useIntl внутри функции и просто передает в intl качестве параметра, это BreadcrumsList больше не будет перехватом, поскольку внутри него не используется какой-либо перехват. Но все же я бы рекомендовал использовать его как const list = BreadcrumbsList(intl)

5. Я бы не рекомендовал это

Ответ №1:

На BreadcrumbsList самом деле это пользовательский хук, чтобы придерживаться правил хуков, вам нужно вызвать его на уровне компонента:

 // Add "use" prefix as its a custom hook
const useBreadcrumbsList = () => {
  const intl = useIntl();

  return [
    { label: intl.formatMessage({ id: "Home" }), path: "/", active: false },
    {
      label: intl.formatMessage({ id: "Account" }),
      path: "/accounts",
      active: false,
    },
    {
      label: intl.formatMessage({ id: "This Account" }),
      path: "/accounts",
      active: true,
    },
  ];
};

// Usage
const Component = () => {
  const breadcrumbsList = useBreadcrumbsList();
  return <Breadcrumbs list={breadcrumbsList} />;
};