Home > Back-end >  TypeScript, React: map array and pass down informations
TypeScript, React: map array and pass down informations

Time:12-06

I'm trying to map through an array loaded from redux store, map through and pass down the information to a new component.

This is what the object from store looks like:

tasks: {
    results: [
        id: number,
        name: string,
    ]
}

The component where the informartion will be passed down to is a simple table row:

interface TaskProps {id: number, name: string}

const TaskTableRow: FC<TaskProps> = ({id, name}) => {
    return(
        <tr>
            <td>{id}</td>
            <td>{name}</td>
        </tr>
    )
}
export default TaskTableRow

My table component looks similiar to this:

interface TaskProps {id: number, name: string}

const TaskTable = () => {

    ...        
    const tasks = useSelector((state: TasksState) => state.tasks)
    ...

    const content = tasks.results ?
        tasks.results.map<TaskProps>(
            item => <TaskTableRow id={item.id} name={item.name} />
        ) : []

    return (
        ...
        <tbody>
            { content }
        </tbody>    
        ...
    );
}
export default TaskTable

My idea was to access the data via item.something, but right now the complete <TaskTableRow />-Element is marked as error with the following information TS2739: Type 'ReactElement<any, any>' is missing the following properties from type 'TaskProps': id, name, slug, status.

What am I missing here, or is the whole approach wrong?

CodePudding user response:

I found the problem here, you are accessing the array of tasks INSTEAD of the task element it self. Because the use selector returns an array so, the array does not have the values id, names etc.(That's why there's a error) So, Here's the final code:

interface TaskProps {
    id: number,
    name: string
}

const TaskTable = () => {

    ...
    const tasks = useSelector((state: TasksState) => state.tasks)
        ...

        const content =
            tasks.results.map(
                item => < TaskTableRow id = {
                    item.id
                }
                name = {
                    item.name
                }
                />
            )

    return (
        ...
        <
        tbody > {
            content
        } <
        /tbody>    
        ...
    );
}
export default TaskTable;

Also, you have a weird data structure, you cannot have elements in a array, instead you can have a array OF OBJECTS WITH THE ELEMENTS! So, you should change the data interface to:

tasks: {
    results: [{
        id: number,
        name: string,
    } {
        id: number,
        name: string,
    } {
        id: number,
        name: string,
    } {
        id: number,
        name: string,
    }]
    ...
}

Hope this helps

  • Related