0

I'm facing a wired issue when adding a new item to the start of the array

checkout the example

class Demo extends React.Component {
    constructor(props) {
        super(props);
        this.state = {arr: [{title: 3}, {title: 2}, {title: 1}]};
    }

    render() {
        return <div>
            {
                this.state.arr.map((item, index) => <Element title={item.title} isNew={item.isNew}
                                                             key={index}/>
                )}
            <button onClick={() => {
                const arr = [...this.state.arr];
                const newItem = this.state.arr.length + 1;
                arr.unshift({title: newItem, isNew: true});
                this.setState({arr: arr});
            }}>ADD ELEMENT TO START
            </button>
        </div>
    }
}

class Element extends React.Component {

    constructor(props) {
        super(props);
        console.log('constructor : ', this.props.title);
    }

    componentDidMount() {
        console.log('componentDidMount : ', this.props.title);
    }

    render() {
        return <span style={{padding : '0 8px' , color: this.props.isNew ? 'red' : 'black'}}>{this.props.title}</span>
    }

}

ReactDOM.render(<Demo/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


<div id="root"></div>

checkout the log when adding a new item to the start of the array, it shows the props of the last item of the array, not the first (since we add the item to the start).

I'm changing the state as required, the rendering is correct but the constructor of the wrong component(the last component) gets called the same goes for componentDidMount.

the app will work perfectly when adding the item to the end of the array but not the opposite.

1 Answer 1

2

It looks like a misuse of key in React.

Your <Element key={index} ... /> code uses the index of the state.arr array to key your items and React uses that key to figure out if anything has changed.

When you add an item to the start, the new item gets assigned the key 0, which already existed in the old item list, so React will notice no difference and not update the first 3 elements. On the fourth element, it will try to render the new element, but the 4th thing in the array is actually the last element of the original array.

Try indexing on the unique part of your object, e.g. the title or something, so React can correctly figure out when to update what.

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

Comments

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.