Как я могу создать пользовательский компонент динамически по строке - PullRequest
0 голосов
/ 30 апреля 2020

Привет мне нужно помочь с моим методом для создания списка пользовательских компонентов. Этот метод имеет одинаковые логики c для 4 компонентов (Пакет, Тема, Часть, Знания). Единственное, что мне нужно изменить, - это компонент, который я нажимаю на список.

Я пробовал что-то подобное, но это странная ошибка:

index.js:1 Warning: <Package /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
export class SubjectDashboardUtils {
    /**
     * Make list of Components of certain type
     * @param {[]} list
     * @param {Number} itemType
     * @return {any} items
     */
    static makeListOfTypedItems(list: [], itemType: string): any {
        console.log(list);
        console.log(itemType);
        const items = [];
        list.forEach((item, key) => {
            const subjectPartComponent = React.createElement('Package', {key: key, data: item}, itemType);
            items.push(subjectPartComponent);
        });
        return items;
    }
}

Ответы [ 2 ]

0 голосов
/ 30 апреля 2020

Вы не должны использовать строки, если они не могут быть обработаны. Вот безопасное для типов решение.

export type TypedItems = Package | Theme | Part | Knowledges;

export class SubjectDashboardUtils {
    static makeListOfTypedItems<T extends TypedItems>(list: any[], itemType: {new(): T; }): (T)[] {
        console.log(list);
        console.log(itemType);
        const items = [];
        return list.map((data, key) => {
            return React.createElement(itemType, {key, data})
        });
    }
}


// Use it like so

const packages = SubjectDashboardUtils.makeListOfTypedItems(['data'], Package);
const parts = SubjectDashboardUtils.makeListOfTypedItems(['data'], Part);

Преимущество этого заключается в наследовании безопасности типов. Возможно, вы даже можете иметь тип list, не являющийся таковым, но для этого я не знаю достаточно React.

0 голосов
/ 30 апреля 2020

React.createElement нужен класс / функция компонента для создания компонентов, а не строка. Строки предназначены только для создания элементов DOM, и они должны начинаться со строчной буквы.

Сделайте это вместо:

import Package from '...';

React.createElement(Package, ...);

Если вам нужно параметризовать создание элементов, вы можете просто передать типы компонентов вокруг, как и любая другая переменная. Например, если вы хотите изменить makeListOfTypedItems на использование типа компонента dynamici c, он может выглядеть примерно так (извините, не поймите намерения вашего исходного кода, поэтому они могут не соответствовать вашим ожиданиям):

import { ComponentType } from 'react';

// ...

export class SubjectDashboardUtils {
  static makeListOfTypedItems<
    DataType, 
    Cmp extends ComponentType<{ data: DataType }>
  >(list: Array<DataType>, DynamicComponent: Cmp) {
    return list.map((item, key) => <DynamicComponent key={key} data={item}/>);
  }
}

Это будет называться как:

SubjectDashboardUtils.makeListOfTypedItems(items, Package);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...