0

I'm have difficulties to convert a class component to functional. I have watched multiple examples for doing this task, but still I know the basics. How can I change my code to be a functional component with using useState and useEffect hooks and maybe if someone has some resources where I can find the best practices on this topic? Here is the example of the code that I'm trying to convert:

import React, { Component } from "react";
import { storeProducts, detailProduct } from "./data";

const ProductContext = React.createContext();
//Provider
//Consumer

class ProductProvider extends Component {
    state = {
        products: [],
        detailProduct: detailProduct
    };

    componentDidMount() {
        this.setProducts();
    }

    setProducts = () => {
        let tempProducts = [];
        storeProducts.forEach(item => {
            const singleItem = {...item};
            tempProducts = [...tempProducts, singleItem];
        })
        this.setState(() => {
            return {products: tempProducts }
        });
    };

    handleDetail = () => {
        console.log("hello from detail");
    };

    addToCart = () => {
        console.log("hello from addToCart");
    };
render() {
    return (
            <ProductContext.Provider value={{
                ...this.state,
                handleDetail: this.handleDetail,
                addToCart: this.addToCart
            }}>
                {this.props.children}
            </ProductContext.Provider>
    );
}
}
0

2 Answers 2

1

You have to use useContext in functional components to get the context.

const ctx = React.createContext();

function ProductProvider(props) {
  const [products, setProducts] = React.useState([]);
  const [detailProduct, setDetailProduct] = React.useState(detailProduct);
  const ProductContext = React.useContext(ctx);

  React.useEffect(() => {
    handleProducts();
  }, []);

  function handleProducts() {
    let tempProducts = [];
    storeProducts.forEach(item => {
      const singleItem = { ...item };
      tempProducts = [...tempProducts, singleItem];
    });

    setProducts(tempProducts);

    // it could simple be written as
    setProducts(storeProducts);
  }

  function handleDetail() {
    console.log("hello from detail");
  }

  function addToCart() {
    console.log("hello from addToCart");
  }

  return (
    <ProductContext.Provider
      value={{
        products,
        detailProduct,
        handleDetail,
        addToCart
      }}
    >
      {props.children}
    </ProductContext.Provider>
  );
}
Sign up to request clarification or add additional context in comments.

Comments

0

I have tried @Prateek Thapa code, but it is showing me the error that ProviderContext is not defined. The error is showing because after my function I have a constant:
const ProductCounsumer = ProductContext.Consumer
which is not in the function.
Also I changed my const name in my data.js to 'detailedProduct' because it has the same name as the const in the useEffect line. So after these changes I have this example with no errors, but still I am not sure if this work like it should be. Can this work without useContext if I have this:

import React, { useState, useEffect } from "react";
import { storeProducts, detailedProduct } from "./data";

const ProductContext = React.createContext();
//Provider
//Consumer

function ProductProvider(props) {
    const [products, setProducts] = useState([]);
    const [detailProduct, setDetailProduct] = useState(detailedProduct);

    useEffect(() => {
      handleProducts();
    }, []);

    function handleProducts() {
      let tempProducts = [];
      storeProducts.forEach(item => {
        const singleItem = { ...item };
        tempProducts = [...tempProducts, singleItem];
      });

      setProducts(tempProducts);

      setProducts(storeProducts);
    }

    function handleDetail() {
      console.log("hello from detail");
    }

    function addToCart() {
      console.log("hello from addToCart");
    }

    return (
      <ProductContext.Provider
        value={{
          products,
          detailProduct,
          handleDetail,
          addToCart
        }}
      >
        {props.children}
      </ProductContext.Provider>
    );
  }
const ProductConsumer = ProductContext.Consumer;

export { ProductProvider, ProductConsumer };

1 Comment

See again, you're missing useContext inside your function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.