Недопустимая поддержка `children` типа` string`, переданная в `ForwardRef (ListItemIcon)` при использовании .map для создания элементов списка MUI - PullRequest
0 голосов
/ 11 января 2020

Итак, я пытаюсь создать динамическую c навигационную боковую панель для моего приложения реакции с пользовательским интерфейсом материалов. Я сохранил всю необходимую мне информацию в БД. Затем я извлекаю информацию из БД и использую .map для создания ссылок на боковую панель. У меня все работает, кроме "part, те, которые не визуализируются. При отображении данных в мой" шаблон "появляется следующая ошибка:

Warning: Failed prop type: Invalid prop `children` of type `string` supplied to `ForwardRef(ListItemIcon)`, expected a single ReactElement.

мой исходный массив:

[{…}, {…}, {…}, {…}]
0:{id: 0, label: "Dashboard", link: "/dashboard", icon: "<HomeIcon />"}
1: {id: 1, label: "test", link: "/test", icon: "<SettingsInputComponentIcon />"}
2: {id: 2, label: "test1", link: "/test1", icon: "<TypographyIcon />"}
3: {id: 3, label: "test2", link: "/test2", icon: "<NotificationsIcon />"}

Я полагаю, что проблема заключается в том, что поле "icon" заключено в двойные кавычки. Я пытался получить значение иконки из кавычек с помощью следующих методов:

for (var i = 0; i < data.length; i++) {
        data[i] = data[i].icon.replace(/"/g, "");

или просто помещал его, когда я сопоставление так:

    <ListItemIcon>
      {icon.replace(/"/g, "")}
    </ListItemIcon>

Есть ли одобренный способ сделать это?

РЕДАКТИРОВАТЬ:

Я хотел бы отметить, что я импортирую значки из пользовательского интерфейса материала следующим образом:

import {
  Home as HomeIcon,
  NotificationsNone as NotificationsIcon,
  FormatSize as TypographyIcon,
  ArrowBack as ArrowBackIcon,
  SettingsInputComponent as SettingsInputComponentIcon
} from "@material-ui/icons";

1 Ответ

1 голос
/ 11 января 2020

JSX! == HTML

JSX - это расширенный набор JavaScript, что означает, что вы не можете рассматривать JSX как строку, как с необработанным HTML.

Если вы используете значки Material UI, вам нужно импортировать их реализацию как любой другой компонент и использовать ссылку в ваших данных.

import { AccessAlarm, ThreeDRotation } from '@material-ui/icons';

export const nav = [
  { id: 1, label: "test", link: "/test", NavIcon: AccessAlarm },
  { id: 2, label: "test2", link: "/test2", NavIcon: ThreeDRotation }
];

ListItemIcon и React Element

ListItemIcon children prop ожидает один React Element .

Содержимое компонента, обычно Icon, SvgIcon или @material-ui/icons SVG icon element.

Элемент является визуализированным компонентом React, например, простым объектом, возвращаемым React.createElement. Хотя мы не хотим предварительно визуализировать их вне цикла рендеринга React, так как это испортит жизненный цикл компонентов Icon.

Чтобы достичь этого, оставляйте только тип компонента вместо строки.

{
  id: 3,
  label: "test2",
  link: "/test2",
  NavIcon: NotificationsIcon // also notice the capital "NavIcon" key.
}

Затем визуализируйте значок, используя его тип. Пример примерно такой:

{data.map(({ id, label, link, NavIcon }) => (
  <ListItem key={id}>
    <ListItemText primary={label} />
    <ListItemIcon>
      <NavIcon />
    </ListItemIcon>
  </ListItem>
))}

Динамически загружаемые значки

Если вы действительно не можете изменить формат базы данных, можно санировать имена значков и загружать их с помощью имя позже, используя UI материала Icon компонент .

children: имя лигатуры шрифта значка.

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

import Icon from '@material-ui/core/Icon';

// somewhere
const data = [
  { id: 1, label: "test", link: "/test", icon: "AccessAlarm" },
  { id: 2, label: "test2", link: "/test2", icon: "ThreeDRotation" }
]

// then when rendering
{data.map(({ id, label, link, icon }) => (
  <ListItem key={id}>
    <ListItemText primary={label} />
    <ListItemIcon>
      <Icon>{icon}</Icon>
    </ListItemIcon>
  </ListItem>
))}

Но вы чаще всего сохраняете имя, которое пользовательский интерфейс Material использует для идентифицируйте свои значки.


Обратите внимание, что строка не содержит своих собственных кавычек как часть своего значения, поэтому .replace(/"/g, "") вообще ничего не делает и возвращает ту же строку, если у нее не было других " внутри, как в кавычках.

console.log("<SettingsInputComponentIcon />".replace(/"/g, ""))
// => "<SettingsInputComponentIcon />"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...