Search code examples
reactjstypescriptjsxtsxreact-tsx

React typescript recognizes array as object


new to react and js in general so it might be a dumb question but I can't sort it out.

I have a component like so:

export interface TableViewContainerProps {
    header: WorthSummaryContainerProps
    content: TableViewRowProps[]
}

export const TableViewContainer = (props: TableViewContainerProps) => {
    console.log('content type is ', typeof(props.content))
    console.log('content is ', props.content)
    return (
        <div id="tableview-container">
            <div id="tableview">
                <TableViewHeader {...props.header}/>
                <TableViewContentList {...props.content} />
                <div id="tableview-footer">
                </div>
            </div>
        </div>
    )
}

So when I print it it's an array of objects, all good. TableViewContentList gets the content as props:

export const TableViewContentList = (props: TableViewRowProps[]) => {
    console.log('type of TableViewContentList props is: ', typeof(props), props)
    const tableViewContents = props.map((row) => console.log('row'))

    return (
        <div id="tableview-content-list">
            {tableViewContents}
        </div>
    )
}

so when I print it here it's an object not an array anymore and it breaks at the .map. Can someone help me out please? I feel like I'm missing something minor.


Solution

  • Spread syntax (...) will give you an object when you apply it on an array inside an object.

    type TableViewRowProps  = number;
    interface TableViewContainerProps {
        content: TableViewRowProps[]
    }
    
    const props = {content: [1,2,3]}
    
    const b = {...props.content}
    console.log(b) // { "0": 1, "1": 2, "2": 3 }. 
    

    So the TableViewContentList get the props: props[0], props[1] and props[2], it's wrong.

    All properties passed into a component will be attached in props, that's why you got an object. props will always be an object. So you'd better pass the content like this:

    <TableViewContentList {...props} />
    

    Or this:

    <TableViewContentList content={props.content} />
    

    Then you can map it to row:

    export default function TableViewContentList(props: { content: TableViewRowProps[] }) {
      const tableViewContents = props.content.map((row) => console.log('row'));
    
      return <div id="tableview-content-list">{tableViewContents}</div>;
    }