Home > Software design >  Warning: <Element /> is using incorrect casing. Use PascalCase for React components, or lowerc
Warning: <Element /> is using incorrect casing. Use PascalCase for React components, or lowerc

Time:01-27

I'm trying to automatically create React Elements from strings corresponding to the react-icons library. But I am getting the following errors in the console:

  • Warning: <RiHeartPulseFill /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
  • Warning: The tag <RiHeartPulseFill> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.

Currently I have a data file that consists of a name and iconName (see below)

const categoriesData = [
    {
        name: 'Vitals',
        iconName: 'RiHeartPulseFill',
    },
    {
        name: 'Body',
        iconName: 'RiBodyScanFill',
    },
    {
        name: 'Sleep',
        iconName: 'RiHotelBedFill',
    },
    {
        name: 'Metabolism',
        iconName: 'RiLungsFill',
    },
    {
        name: 'Stress',
        iconName: 'RiMentalHealthFill',
    },
    {
        name: 'Strength & Training',
        iconName: 'RiRunFill',
    },
    {
        name: 'Lifestyle',
        iconName: 'RiCellphoneFill',
    },
]

export default categoriesData

I want to dynamically render React elements with the exact name as the iconName in the above datafile as React-icons require specific elements with those names.

Then I try to create a list of navigation links (using the React Router <Link> syntax and adding a React-icon Name. See the code below:

const menuCategories = categoriesData.map((category) => {
        const IconElement = category.iconName

        return (
            <Link
                to={`/data/${category.name.toLowerCase()}`}
                key={category.name}
                className="flex flex-row items-center gap-2"
            >
                <IconElement />
                {category.name}
            </Link>
        )
    })

The issue I run into is the following error: Warning: <RiHeartPulseFill /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.

I does not seems to be incorrect as it actually IS PascalCase. However when I check dev tools I see the following: <riheartpulsefill></riheartpulsefill>

I have no Idea why this happens. Any solutions?

Extra: Does anyone know how I can also import those icon names based on the initial data files. I'm thinking about creating an icon selection tool, so only the selected icons should be imported from the react-icons lib.

CodePudding user response:

If you want to dynamically render these icon components then you'll need to import and specify them in the config instead of strings corresponding to their names.

Example:

import {
  RiHeartPulseFill,
  RiBodyScanFill,
  RiHotelBedFill,
  RiLungsFill,
  RiMentalHealthFill,
  RiRunFill,
  RiCellphoneFill,
} from "react-icons/ri";

const categoriesData = [
  {
    name: 'Vitals',
    iconName: RiHeartPulseFill,
  },
  {
    name: 'Body',
    iconName: RiBodyScanFill,
  },
  {
    name: 'Sleep',
    iconName: RiHotelBedFill,
  },
  {
    name: 'Metabolism',
    iconName: RiLungsFill,
  },
  {
    name: 'Stress',
    iconName: RiMentalHealthFill,
  },
  {
    name: 'Strength & Training',
    iconName: RiRunFill,
  },
  {
    name: 'Lifestyle',
    iconName: RiCellphoneFill,
  },
];

export default categoriesData;
const menuCategories = categoriesData.map((category) => {
  const IconElement = category.iconName;

  return (
    <Link
      to={`/data/${category.name.toLowerCase()}`}
      key={category.name}
      className="flex flex-row items-center gap-2"
    >
      <IconElement />
      {category.name}
    </Link>
  );
});

An alternative is to create and export a lookup object for the icon components.

import {
  RiHeartPulseFill,
  RiBodyScanFill,
  RiHotelBedFill,
  RiLungsFill,
  RiMentalHealthFill,
  RiRunFill,
  RiCellphoneFill,
} from "react-icons/ri";

export const iconMap = {
  RiHeartPulseFill,
  RiBodyScanFill,
  RiHotelBedFill,
  RiLungsFill,
  RiMentalHealthFill,
  RiRunFill,
  RiCellphoneFill,
};

const categoriesData = [
  {
    name: 'Vitals',
    iconName: 'RiHeartPulseFill',
  },
  {
    name: 'Body',
    iconName: 'RiBodyScanFill',
  },
  {
    name: 'Sleep',
    iconName: 'RiHotelBedFill',
  },
  {
    name: 'Metabolism',
    iconName: 'RiLungsFill',
  },
  {
    name: 'Stress',
    iconName: 'RiMentalHealthFill',
  },
  {
    name: 'Strength & Training',
    iconName: 'RiRunFill',
  },
  {
    name: 'Lifestyle',
    iconName: 'RiCellphoneFill',
  },
];

export default categoriesData;
const menuCategories = categoriesData.map((category) => {
  const IconElement = iconMap[category.iconName];

  return (
    <Link
      to={`/data/${category.name.toLowerCase()}`}
      key={category.name}
      className="flex flex-row items-center gap-2"
    >
      <IconElement />
      {category.name}
    </Link>
  );
});

CodePudding user response:

Use React.createElement. Take a look here to see how: Create react component dynamically - at the core its this snippit of code.

var component = Components[itemData['itemClass']]);
return React.createElement(component, {
    data: itemData,
    key: itemData['id']
});
  • Related