Sam
Sam

Reputation: 505

Why isn't the component rendering the correct information? ReactJS

I'm rendering an array of values and I have a two buttons, one to Add and another to Remove. Everything works the way it should but when I click Remove, the element in the correct index gets removed from the array but when it renders again, it removes the last entry, and not the entry at that specific index.

For example: (left side is webpage, right side is console)

enter image description here

Currently the array is ["hello", "world", "everyone"] and let's say I want to remove "world" and I click the Remove button next to it, the array updates correctly (I did a console.log) and it becomes ["hello", "everyone"], it re-renders but it shows it as if the array was ["hello", "world"] and renders it incorrectly:

enter image description here

I'm not sure what I did incorrectly with my code as the array gets updated correctly and everything else seems to be okay.

    childChange: function(name, valid, value) {

        this.state.values = this.props.values;
        var pattern = /[0-9]+/;                                             // Using regex to find last digits from 0-9
        var match = name.match(pattern);                                    // Update state
        var i = parseInt(match);                                            // Parse char into int
        // console.log(match);

        this.state.values[i] = value;

        this.setState(this.state);

        this.props.callback(                                                // Call parent callback
            this.props.name,
            this.props.node.valid(this.state.values),
            this.state.values
        );
    },

    addEmptyItem: function() {

        this.state.values = this.props.values;
        this.state.values.push("");
        this.setState(this.state);

    },

    removeItem: function(ev) {

        console.log(ev.currentTarget.dataset.index);
        var i = parseInt(ev.currentTarget.dataset.index);
        this.state.values = this.props.values;
        this.state.values.splice(i,1);
        console.log(this.state.values);
        this.setState(this.state.values);

    },

        render: function() {
            var that = this;

            console.log("===RENDER===");

            return (
                <div id = "form">
                {this.props.values.map(function(v, i) {
                    return (

                        <div>
                            {(that.props.node.get().constructor.name === "Parent") ?
                            <ParentComponent
                                name={that.props.name + i}
                                key={i}
                                timer={that.props.timer}
                                callback={that.childChange}
                                values={v}
                                newParent={that.props.node.get()}
                            />
                            :
                            <div>
                                <NodeComponent
                                    name={that.props.name + i}
                                    key={i}
                                    timer={that.props.timer}
                                    callback={that.childChange}
                                    value={v}
                                    newNode={that.props.node.get()}
                                />

                            </div>

                            }
                            <button data-index={i} onClick={that.removeItem}>Remove
                            </button>
                        </div>

                    )
                })}
                <button onClick={() => that.addEmptyItem()}>Add
                </button>

                </div>
           )

        }

Upvotes: 0

Views: 61

Answers (1)

Tom Mendelson
Tom Mendelson

Reputation: 625

Change your function to look like this:

removeItem: function(ev) {

        console.log(ev.currentTarget.dataset.index);
        var i = parseInt(ev.currentTarget.dataset.index);
        let values = [...this.props.values];
        values.splice(i,1);
        console.log(this.state.values);
        this.setState(values);

    }

Why? when you use react state, you never changing it directly. you might look about it in this article. what you did here, is you changed the state and then you called 'setState', that doesn't work. you should create new variable, manipulate over the new variable, and then call the setState with the new variable

Upvotes: 2

Related Questions