Can't increase quantity in nested array

Viewed 107

I can’t increase the quantity in a nested array in any way, I have already tried many ways. I've tried spread, but it doesn't work. I need quantity to increase for a specific id. Please, instead of criticism, please write how to solve and what I'm doing wrong. I will be grateful for help. Updated with suggestions

App.js

import React, { Component } from "react";
import ClickId from "./ClickId";
import Cart from "./Cart";
import { BrowserRouter, Route, Routes } from "react-router-dom";

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      products: [
        {
          id: "Adidas"
        },
        {
          id: "Puma"
        },
        {
          id: "Nike"
        }
      ],
      countId: {
        quantityId: []
      }
    };
  }
  IncrementItem = (id) => {
    this.setState((prevState) => {
      let newState = JSON.parse(JSON.stringify(prevState)); // deep copy
      let products = this.state.products.map((p) => p.id);
      for (let i = 0; i < newState.countId.quantityId.length; i++) {
        if (newState.countId.quantityId[i].id === products) {
          newState.countId.quantityId[i].quantity += 1;
        }
      }
      return newState;
    });
  };
  DecrementItem = (id) => {
    this.setState((prevState) => {
      let newState = JSON.parse(JSON.stringify(prevState)); // deep copy
      for (let i = 0; i < newState.countId.quantityId.length; i++) {
        if (newState.countId.quantityId[i].id === this.state.products.id) {
          newState.countId.quantityId[i].quantity -= 1;
        }
      }
      return newState;
    });
  };
  CountId = (event) => {
    this.setState({
      countId: {
        ...this.state.countId,
        quantityId: this.state.countId.quantityId.concat({
          id: event.currentTarget.id,
          quantity: 1
        })
      }
    });
  };
  render() {
    return (
      <div>
        <BrowserRouter>
          <Routes>
            <Route
              path="/ClickId"
              element={
                <ClickId CountId={this.CountId} countId={this.state.countId} />
              }
            />
            <Route
              path="/Cart"
              element={<Cart IncrementItem={this.IncrementItem} />}
            />
          </Routes>{" "}
        </BrowserRouter>{" "}
      </div>
    );
  }
}

ClickId.js

import React, { Component } from "react";

export default class ClickId extends Component {
  constructor(props) {
    super(props);
    this.state = {
      products: [
        {
          id: "Adidas"
        },
        {
          id: "Puma"
        },
        {
          id: "Nike"
        }
      ]
    };
  }
  countId = () => {
    if (this.props.CountId) {
      this.props.CountId();
    }
  };
  render() {
    return (
      <div>
        {this.state.products.map((p) => {
          return (
            <div id={p.id} onClick={this.props.clickId}>
              ClickId
            </div>
          );
        })}
      </div>
    );
  }
}

Cart.js

import React, { Component } from "react";

export default class Cart extends Component {
  constructor(props) {
    super(props);
    this.state = {
      products: [
        {
          id: "Adidas"
        },
        {
          id: "Puma"
        },
        {
          id: "Nike"
        }
      ]
    };
  }
  render() {
    return (
      <div>
        {this.state.products.map((p) => {
          return (
            <div>
              <button onClick={() => this.props.IncrementItem(p.id)}>
                +
              </button>
              <div className='s.count'>
                {JSON.stringify(
                  value.state.countId.quantityId.map((i) => i.quantity)
                )}
              </div>
              <button onClick={() => this.props.DecrementItem(p.id)}>
                -
              </button>
            </div>
          );
        })}
      </div>
    );
  }
}
1 Answers

You return { quantitiy: "{{updated value}}" } from setState.

However, setState's callback should return the same structure as this.state has (some fields of the first level can be omitted).

In your case it can look like

this.setState(prevState => {
  var newState = JSON.parse(JSON.stringify(prevState)) // deep copy
  newState.countId.quantityId[0].quantity = "{{updated value}}"
  return newState
})

Example

import React, { Component } from "react";

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      products: [
        { id: 1, name: "Adidas", quantity: 1 },
        { id: 2, name: "Puma", quantity: 1 }
      ]
    };
  }
  IncrementItem = (id) => {
    this.setState((prevState) => {
      var newState = JSON.parse(JSON.stringify(prevState)); // deep copy
      for (let i = 0; i < newState.products.length; i++) {
        if (newState.products[i].id === id) {
          newState.products[i].quantity += 1;
        }
      }
      return newState;
    });
  };
  render() {
    return (
      <div>
        {this.state.products.map((product) => {
          return (
            <button onClick={() => this.IncrementItem(product.id)}>
              {product.name} +
            </button>
          );
        })}
        <div>{JSON.stringify(this.state)}</div>
      </div>
    );
  }
}
Related