When I lifting state up my handlers doesn't work

Viewed 31

my React App has some component

  1. App
  2. Productlist
    2/1. Product
  3. NavBar

I want to build a product counter in NavBar for this I must lift the state up from Productlist to App and lift handlers up.

now when I Click the handlers my handlers don't work

this is my App.jsx

import React, { Component } from 'react';
import styles from './App.module.css'
import Productlist from './Productlist/Productlist';
import NavBar from './NavBar/NavBar';


class App extends Component {
    state = {
        products: [
            { name: "React", price: 90, id: 1, quantity: 1 },
            { name: "Node", price: 80, id: 2, quantity: 2 },
            { name: "Iionic", price: 75, id: 3, quantity: 1 },
            { name: "React Native", price: 60, id: 4, quantity: 3 },
            { name: "veu", price: 100, id: 5, quantity: 2 },
        ],
    }

    //handlers

    removeHandeler(id) {
        const products = [...this.state.products];
        const filteredProducts = products.filter(p => p.id !== id);
        this.setState({ products: filteredProducts });
    }

    incrementHandeler(id) {
        const products = [...this.state.products];
        const selecteditem = products.find(p => p.id === id);
        selecteditem.quantity++;
        this.setState({products : products})
    }

    decrementHandeler(id) {
        const products = [...this.state.products];
        const selectedItem = products.find(p => p.id === id)
        selectedItem.quantity--;
        if (selectedItem.quantity < 1) {
            this.removeHandeler(id)
        }else{
            this.setState({products})
        }
    }

    inputHandeler(event, id) {
        const products = [...this.state.products];
        const selectedItem = products.find(p => p.id === id)
        selectedItem.name = event.target.value
        this.setState({products})
    }

    // rendering
    render() {
        return (
            <React.StrictMode>
                <div className={styles.container}>
                    
                    <NavBar />
                    <Productlist 
                    products={this.state.products}
                    onDelete={this.removeHandeler}
                    onIncrement={this.incrementHandeler}
                    onDecrement={this.decrementHandeler}
                    onChange={this.inputHandeler}
                    />
                </div>
            </React.StrictMode>
        );
    }
}

and this is my Productlist.jsx

import Product from "./Products/Products";
import React, { Component } from 'react';
import styles from "./Productlist.module.css";

class ProductList extends Component {
    //rendering
    render() {
        
        // 0 product erorr
        if (this.props.products.length === 0) {
            return  <div className={styles.container}>
                        <img src="./img/error.png" alt="error"/>
                        <p className={styles.productErorText}>there is not product in cart</p>
                    </div>
        }

        return (
            <div className={styles.container}>
                {this.props.products.map((product, index) => {
                    return (
                            <Product
                                product={product}
                                key={index}
                                onDelete={() => this.props.onDelete(product.id)}
                                onIncrement={() => this.props.onIncrement(product.id)}
                                onChange={(e) => this.props.onChange(e, product.id)}
                                onDecrement={() => this.props.onDecrement(product.id)}
            />)
        })
    }
            </div>

);



    };
}

export default ProductList;

React doesn't show me an error but in console, I have one error and when I click the handlers show me another error

this is both errors

1 Answers

in App.js you should bind the methods

<Productlist 
  products={this.state.products.bind(this)}
  onDelete={this.removeHandeler.bind(this)}
  onIncrement={this.incrementHandeler.bind(this)}
  onDecrement={this.decrementHandeler.bind(this)}
  onChange={this.inputHandeler.bind(this)}
/>

or use arrow function syntax:

incrementHandeler = (id) => {
    const products = [...this.state.products];
    const selecteditem = products.find(p => p.id === id);
    selecteditem.quantity++;
    this.setState({products : products})
}
Related