0

In the project there is an array of objects used for populating the breadcrumb:

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

it is used to populate the list in the Breadcrumbs component:

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

...

<Breadcrumbs list={BREADCRUMBS_LIST} />

Everything works fine.

The problem appears when we need to translate those labels based on the user's language. For this, we are using react-intl.

So, I transformed the original array into a component of this form:

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
    }
  ];
};

and use it like this:

<Breadcrumbs list={BreadcrumbsList} />

it seems to be wrong because it returns an error saying:

Cannot read property 'map' of undefined.

In that component, the list was used with map: {list.map(({path, label, active}, index) => {...})

Any ideas how to solve this problem?

Leo Messi
  • 5,157
  • 14
  • 63
  • 125
  • You are passing reference of BreadcrumbList instead of calling it, so will receive list as an instance of function and map will not work on that. – Sameer Reza Khan Feb 02 '21 at 11:04
  • Just naming the function with UpperCase name doesn't mean its a Component. `BreadcrumbsList` is only a function & you're using a hook inside a function which is not recommended by react team. Try initializing the hook outside the `BreadcrumbsList` function in where you've used it & just pass the `intl` as a parameter of the function. Also you've to invoke the function, you can't just pass this as a `Function`. So basically call it inside `` – KR Tirtho Feb 02 '21 at 11:06
  • @KRTirtho Calling `BreadcrumbsList()` won't help, it's a custom hook that violates the rules. – Dennis Vash Feb 02 '21 at 11:08
  • @DennisVash, if he isn't using the `useIntl` inside the function & just passing the `intl` as a parameter then `BreadcrumsList` will no longer be a hook as its not using any hook inside of it. But still I'd recommend using it as `const list = BreadcrumbsList(intl)` – KR Tirtho Feb 02 '21 at 12:14
  • I wouldn't recommend it – Dennis Vash Feb 02 '21 at 12:15

1 Answers1

0

Your BreadcrumbsList is actually a custom hook, in order to stick with the Rules of Hooks you need to call it on component's level:

// 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} />;
};
Dennis Vash
  • 50,196
  • 9
  • 100
  • 118