0

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

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I am unable to make this work :/ especially part with export type.... I am getting this error ``` Argument of type 'typeof Package' is not assignable to parameter of type 'Package' ```
Type 'typeof Package' is missing the following properties from type 'ThemePartKnowledge': state, componentDidUpdate, render, context, and 4 more. TS
I have updated the types, I had an error there for a minute or two
0

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);

5 Comments

This is not solving my problem. in method above i am getting itemType by parameter. This is string (Package,Theme,Part,Knowledge) and i have to create component with this string
is there any other way how to do this?
i know i could use switch but i hoped there is better way
Why do you have to create with a string? Can't you pass the component type as a parameter instead?
I haven't tested this yet, but something like my edit could work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.