Search code examples
javascriptreactjsreact-props

React.js - Each child in a list should have a unique "key" prop


I'm having problem with the "Each child in a list should have a unique "key" prop" error in my application. I am able to print the table but i'm not sure why its giving me this error as i am providing a unique ID to every item in the list.

I have tried adding a key property to my table header as well but this doesnt fix the errors.

Any ideas would be appreciated

Customers component

export default class Customers extends Component {
    constructor(props) {
        super(props);
        this.state = {
            records: [],
            model: 'Customers',
            columns: ['First Name', 'Last Name', 'Address']
        }
    }

    componentDidMount = () => {
        this.getAllRecords();
    }

    getAllRecords = () => {
        axios.get('api/Customers')
            .then((result) => {
                this.setState({ records: result.data })
                console.log(this.state.records);
            })
            .catch((error) => {
                alert(error);
                console.log(error);
            });
    }

    render() {
        return (
            <div>
                <RecordsTable
                    model={this.state.model}
                    columns={this.state.columns}
                    records={this.state.records}
                    reload={this.getAllRecords}
                />
            </div>
        )
    }
}

Table Component

export default class RecordsTable extends Component {
    constructor(props) {
        super(props);
        this.state = {
        }
    }

    render() {

        const { columns, records, model } = this.props

        return (
            <Table striped>
                <Table.Header>
                    <Table.Row>
                        {
                            columns.map((column) => {
                                return (
                                    <Table.HeaderCell key={column.id}>
                                        {column}
                                    </Table.HeaderCell>
                                )
                            })
                        }
                        <Table.HeaderCell>Actions</Table.HeaderCell>
                        <Table.HeaderCell>Actions</Table.HeaderCell>
                    </Table.Row>
                </Table.Header>

                <Table.Body>
                    {
                        records.map((record) => {
                            return (
                                
                                //Warning: Each child in a list should have a unique "key" prop.
                                <Table.Row key={record.id} > 
                                    {
                                        columns.map((column) => {
                                            if (column === 'First Name') {
                                                return (<Table.Cell>{record.firstName}</Table.Cell>)
                                            }
                                            else if (column === 'Last Name') {
                                                return (<Table.Cell>{record.lastName}</Table.Cell>)
                                            }
                                            else if (column === 'Address') {
                                                return (<Table.Cell>{record.address}</Table.Cell>)
                                            }
                                            else {
                                                return (<Table.Cell>{record.column}</Table.Cell>)
                                            }
                                        })
                                    }
                                    { // Edit Customer Component
                                        model === 'Customers' && <Table.Cell>Edit Customer</Table.Cell>}
                                    {
                                        // Edit Product Component
                                        model === 'Products' && <Table.Cell>Edit Product</Table.Cell>
                                    }
                                    <Table.Cell>Delete</Table.Cell>
                                </Table.Row>
                            )
                        })
                    }
                </Table.Body>
            </Table>
        )
    }
}

Solution

  • From the docs:

    Keys should be given to the elements inside the array to give the elements a stable identity

    You need to set a key prop to every instance where an array .map is involved. You missed it in the <Tabel.Cell> components.

    <Table.Row key={record.id} > 
        {
            columns.map((column) => {
                const key = column['something'];
                if (column === 'First Name') {
                    return (<Table.Cell key={key}>{record.firstName}</Table.Cell>)
                }
                else if (column === 'Last Name') {
                    return (<Table.Cell key={key}>{record.lastName}</Table.Cell>)
                }
                else if (column === 'Address') {
                    return (<Table.Cell key={key}>{record.address}</Table.Cell>)
                }
                else {
                    return (<Table.Cell key={key}>{record.column}</Table.Cell>)
                }
            })
        }
        { // Edit Customer Component
            model === 'Customers' && <Table.Cell>Edit Customer</Table.Cell>}
        {
            // Edit Product Component
            model === 'Products' && <Table.Cell>Edit Product</Table.Cell>
        }
        <Table.Cell>Delete</Table.Cell>
    </Table.Row>
    

    If the problem still persist, you might want to check if there's anywhere else you might've missed the prop.