Reputation: 1042
Hi I need to help with my method for creating list of custom components. This method has same logic for 4 components (Package,Theme,Part, Knowledges). Only one thing i have to change is component which i pushing to list.
I tried something like this, but this throw weird error:
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;
}
}
Upvotes: 0
Views: 564
Reputation: 78840
React.createElement
needs the component class/function to create components, not a string. Strings are only for creating DOM elements, and those must start with a lowercase letter.
Do this instead:
import Package from '...';
React.createElement(Package, ...);
If you need to parameterize the creation of elements, you can just pass component types around like any other variable. For example, if you wanted to change makeListOfTypedItems
to use a dynamic component type, it could look something like this (sorry, don't get your original code's intent, so they might not be what you meant):
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}/>);
}
}
This would be called like:
SubjectDashboardUtils.makeListOfTypedItems(items, Package);
Upvotes: 0
Reputation: 11495
You should not use strings are they are not treed shakable. Here is a type-safe solution.
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);
The benefit of this is inheriting type safety. You could probably even have a type of list
not being any, but for that, I do not know enough of React.
Upvotes: 1