0
votes

(React 16.8.6) I have the problem that when a variable change, it automatically changes also the state even if I don't call any setState. In the handleInputChange when I assign the value, it automatically updates the states clientsData and editedClientsData . I would like to update only editedClientsData.

Here is the code:

1 - set the state (fired on a button click):

getClients(calls) {
axios.all(calls)
    .then(responseArr => {
        let cleanedDate = []
        responseArr.map(el => {
            cleanedDate.push(el.data.data)
        })
        this.setState({
            clientsData: cleanedDate,
            editedClientsData: cleanedDate,
            loading: false
        })
        this.loadDataChart()
    });
}

2 - load the inputs fields

render(){
    return (...
        this.state.editedClientsData.map(this.renderInput)
    ...)
}

renderInput = (client, i) => {
    const { activeYear } = this.state
    return (<tr key={client.id}>
        <td>{client.name}</td>
        <td><Input
            type="number"
            name={client.id}
            id="exampleNumber"
            placeholder="number placeholder"
            value={client.chartData[activeYear].r}
            onChange={this.handleInputChange}
        /></td>
        <td>{client.chartData[activeYear].x}</td>
        <td>{client.chartData[activeYear].y}</td>
    </tr>
    )
}

handleInputChange(event) {
    let inputs = this.state.editedClientsData.slice();
    const { activeYear } = this.state
    for (let i in inputs) {
        if (inputs[i].id == event.target.name) {
            inputs[i].chartData[activeYear]['r'] = parseFloat(event.target.value)
            console.log(inputs)
            // this.setState({ editedClientsData: inputs })
            break;
        }
    }
}

I tried to assign a fixed number I tried to save as const {clientsData} = this.state , updating editedClientsData and the this.setState({clientsData})

All of these tests failed. Hope in your helps, thank you!

1
Your for .. in loop doesn't make sense, are you trying to modify each value in the array?Clarity
Actually this was the last test.. the first version was without the loop and only let { editedClientsData } = this.state const { clientsData, activeYear } = this.state editedClientsData[index].chartData[activeYear][data] = parseFloat(event.target.value) But also this code failed.. I had the same wrong result.f.strazzante
Yes, because if you use index then you're trying to update all the items in array. So how do you know which item needs to be edited?Clarity

1 Answers

0
votes

In the getClients function, you are assigning the same array cleanedDate to both the props (clientsData and editedClientsData) of the state.

Both the properties are pointing to the same array. So edit will be reflected to both the properties. Now, assuming that the array contains objects, so copying the array using slice will also not work, because both the different arrays are containing the references to the same data. Consider the example below:

var a = [{prop: 1}];
var b = a.slice();
var c = a.slice();
console.log(c == b); // false
b[0].prop = 2;
console.log(b[0].prop); // 2
console.log(c[0].prop); // also 2, because slice does shallow copy.

In this case you need to deeply copy the data, so no reference is duplicated. You can use Lodash utility for this or create your own utility for the same.