将 class 个具有状态的组件转换为具有钩子的功能组件
Converting class component with state to functional component with hooks
我很难将 class 组件转换为功能组件。我看过多个执行此任务的示例,但我仍然了解基础知识。我如何使用 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>
);
}
}
您必须在功能组件中使用 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>
);
}
我试过@Prateek Thapa 代码,但它向我显示未定义 ProviderContext 的错误。显示错误是因为在我的函数之后我有一个常量:
const ProductCounsumer = ProductContext.Consumer
不在函数中。
此外,我将 data.js 中的 const 名称更改为 'detailedProduct',因为它与 useEffect 行中的 const 名称相同。因此,在这些更改之后,我有了这个没有错误的示例,但我仍然不确定它是否像它应该的那样工作。如果我有这个,这个可以在没有 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 };
我很难将 class 组件转换为功能组件。我看过多个执行此任务的示例,但我仍然了解基础知识。我如何使用 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>
);
}
}
您必须在功能组件中使用 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>
);
}
我试过@Prateek Thapa 代码,但它向我显示未定义 ProviderContext 的错误。显示错误是因为在我的函数之后我有一个常量:
const ProductCounsumer = ProductContext.Consumer
不在函数中。
此外,我将 data.js 中的 const 名称更改为 'detailedProduct',因为它与 useEffect 行中的 const 名称相同。因此,在这些更改之后,我有了这个没有错误的示例,但我仍然不确定它是否像它应该的那样工作。如果我有这个,这个可以在没有 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 };