Ciuliene
Ciuliene

Reputation: 23

ReactJS - When I change a state, props change too

I've learnt that, in a React component, states can change while props can't, except if the Parent component changes them. Pretty easy to understand. So, now I'm trying to make a parent component with an array, pass it to a child component and assign it to state. I've added another prop to better understand the problem:

import React from "react";
   
 export default function Parent() {
   return <Child list={["1", "3", "4"]} val="val" />;
 }

Here is my Child component that receives props, manage and render them:

class Child extends React.Component {
  state = {
    list: this.props.list,
    val: this.props.val
  };

  onValueChange = (e, i) => {
    let { list } = this.state;
    list[i] = e.target.value;
    this.setState(() => {
      return { list };
    });
  };

  render() {
    console.log(this.props.list[0], this.props.val);
    return (
      <div className="App">
        {this.state.list.map((item, i) => {
          return (
            <input
              key={i}
              value={item}
              onChange={(e) => this.onValueChange(e, i)}
            />
          );
        })}
        <div>
          <input
            value={this.state.val}
            onChange={(e) => {
              this.setState({ val: e.target.value });
            }}
          />
        </div>
      </div>
    );
  }
}

If I try to edit the "val" state (initialized with val prop), val prop doesn't change. Instead if I try to edit one of the items in the array (initialized with list prop) both state and props change!

I expected the props could never change but it seems that if a prop is an array it can

What am I doing wrong?

Here is the codesandbox of this strange behavior:

https://codesandbox.io/s/hidden-darkness-tfoxl?file=/src/App.js

Upvotes: 2

Views: 995

Answers (1)

Reda
Reda

Reputation: 106

Here's what i can recommend:

onValueChange = (e, i) => {
// Copy the list state
    let list = [...this.state.list];
// Make a copy of the item you want to update
    let item = {...list [i]};
// Update it
    item = e.target.value;
// Put it back into the list
    list [i] = item;
// Return the new state
    this.setState({list});
};

Upvotes: 2

Related Questions