Преобразование компонента класса с состоянием в функциональный компонент с помощью перехватов

#reactjs #react-hooks #react-functional-component

#reactjs #реагирующие перехваты #реагирующий функциональный компонент

Вопрос:

У меня возникают трудности с преобразованием компонента класса в функциональный. Я наблюдал за несколькими примерами для выполнения этой задачи, но все же я знаю основы. Как я могу изменить свой код, чтобы он был функциональным компонентом, используя перехваты useState и useEffect и, возможно, если у кого-то есть ресурсы, где я могу найти лучшие практики по этой теме? Вот пример кода, который я пытаюсь преобразовать:

 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>
    );
}
}
  

Ответ №1:

Вы должны использовать useContext в функциональных компонентах, чтобы получить контекст.

 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>
  );
}
  

Ответ №2:

Я попробовал код @Prateek Thapa, но он показывает мне ошибку, что ProviderContext не определен. Отображается ошибка, потому что после моей функции у меня есть константа:
const ProductCounsumer = ProductContext .Потребитель
которого нет в функции.
Также я изменил свое постоянное имя в своем data.js к «detailedProduct», потому что он имеет то же имя, что и const в строке useEffect. Итак, после этих изменений у меня есть этот пример без ошибок, но все же я не уверен, работает ли это так, как должно быть. Может ли это работать без useContext, если у меня есть это:

 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. Смотрите еще раз, вам не хватает useContext внутри вашей функции.