Amber-Williams
Amber-Williams

Reputation: 101

Redux reducer is getting over written by setState or .map() in my React component

When I console.log the this.state.orginalSeries, this.props.demandGraphSeriesDataReducer and newSeries I get all of the same mutated data back.

I tried using .map() and .slice() to not mutate the original reducer data but some how it still is getting mutated. I can also see using Redux Devtools it is mutating the state of the reducer as well.

class DemandSubDemand extends Component {
  constructor(props) {
    super(props);
    this.state = {
      orginalSeries: null
    };
  }
  componentDidMount(){
    const copy = this.props.demandGraphSeriesDataReducer.slice()
    this.setState({
      orginalSeries: copy
    })
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.props.demandGraphSeriesDataReducer!== prevProps.demandGraphSeriesDataReducer) {
      const copy = this.props.demandGraphSeriesDataReducer.slice()
      this.setState({
        orginalSeries: copy
      })
    }
  }

  onValueUpdate(i, value) {
    const newSeries = this.state.orginalSeries.map((line, j) => {
      if(i === j) line.data[i] = line.data[i] + value;
      return line;
    });
  }

render(){
  return <button onClick={()=>this.onValueUpdate(0,100)}> here</button>
}

Upvotes: 2

Views: 136

Answers (2)

markerikson
markerikson

Reputation: 67469

I think the mutation may be here:

  onValueUpdate(i, value) {
    const newSeries = this.state.orginalSeries.map((line, j) => {
      if(i === j) line.data[i] = line.data[i] + value;
      return line;
    });
  }

In particular, line.data[i] = is going to mutate the existing line object in the original array. You would need to make copies of every level of nesting in the data for it to not mutate.

I'd strongly encourage you to use the configureStore() function from Redux Starter Kit, which adds a mutation checker by default. Also, consider using Immer for simpler immutable updates. Redux Starter Kit's createReducer() and createSlice() functions use Immer internally by default.

Upvotes: 1

Amber-Williams
Amber-Williams

Reputation: 101

Using JSON.parse( JSON.stringify( this.props.demandGraphSeriesDataReducer ) ) in place of slice worked per @icepickle 's advice

Upvotes: 0

Related Questions