#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} />;
};