gpt4 book ai didi

javascript - Context API 中的 ReactJS 异步 axios

转载 作者:行者123 更新时间:2023-12-02 20:55:51 24 4
gpt4 key购买 nike

我从 context.js 中的rest-api 获取数据。我将数据分配给状态。以下是 context.js 中的代码:

export class AppProvider extends Component {
state = {
products: [],
cart: [],
dispatch: action => this.setState(state => reducer(state, action))
}

fetchData = async () => {
const products = await axios.get('http://127.0.0.1:4000/product/all', { headers: { "Access-Control-Allow-Origin": "*" } })
this.setState({
products: products.data
})
}

componentDidMount(){
this.fetchData();
}

render() {
return (
<AppContext.Provider value={this.state}>
{this.props.children}
</AppContext.Provider>
)
}
}

我正在其他组件中使用状态数据。但是当刷新页面时,我没有使用其他组件中状态的数据。当页面刷新时,context.js 中的状态变为初始状态。我怎么解决这个问题?这是其他组件的代码:

import React, { useState, useContext, useEffect } from 'react';
import { Button, Badge } from 'reactstrap';
import './ProductDetail.css';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faShoppingCart } from '@fortawesome/free-solid-svg-icons';
import { AppContext } from '../../../context/context';
import { toast, Slide } from 'react-toastify';
toast.configure();
const ProductDetail = props => {
const [inputValue, setInputValue] = useState(1);


const preventNegative = e => {
const value = e.target.value.replace(/[^\d]/, '');
if (parseInt(value) !== 0) {
setInputValue(value);
}
}

const addToCart = (e, productID) => {
// eslint-disable-next-line array-callback-return
const product = products.filter(p => {
// eslint-disable-next-line eqeqeq
if (p.id == productID) {
return p
}
})
console.log(product);
dispatch({
type: 'ADD_TO_CART',
payload: [product, inputValue]
})
toast.success("The product has been added to cart successfully !", {
position: toast.POSITION.TOP_CENTER,
autoClose: 2500,
transition: Slide
})
}



const { products, dispatch } = useContext(AppContext)
const filteredProduct = products.filter(p => p.id == props.match.params.id)

return (
<React.Fragment>
<main className="mt-5 pt-4">
<div className="container dark-grey-text mt-5">
<div className="row wow fadeIn">
<div className="col-md-6 mb-4">
<img src={filteredProduct[0].image} className="img-fluid" alt="" />
</div>
<div className="col-md-6 mb-4">
<div className="p-4">
<div className="mb-3">
<Badge color="primary">New</Badge>
<Badge color="success">Best seller</Badge>
<Badge color="danger">{filteredProduct[0].discountRate}% OFF</Badge>
</div>
<h2 className="h2">{filteredProduct[0].title}</h2>
<p className="lead">
<span className="mr-1">
<del>${filteredProduct[0].prevPrice}</del>
</span>
<span>${filteredProduct[0].price}</span>
</p>
<p className="text-muted">
{filteredProduct[0].detail}
</p>
<form className="d-flex justify-content-left">
<input
min="1"
onChange={(e) => preventNegative(e)}
value={inputValue}
type="number"
aria-label="Search"
className="form-control"
style={{ width: '100px' }} />

<Button onClick={(e) => addToCart(e, filteredProduct[0].id)} color="primary">Add to Cart <FontAwesomeIcon icon={faShoppingCart} /> </Button>

</form>
</div>
</div>
</div>
</div>
</main>
</React.Fragment>

)
}
export default ProductDetail;

最佳答案

您的 AppProvider 组件是正确的,您遇到的唯一问题是因为您从 API 获取结果,并且在 componentDidMount 中执行该操作,这应该是正确的。

但是,当您刷新页面时,AppProvider 中的设置将重置为初始值,并且由于您已经位于 ProductDetail 组件上,因此您甚至可以在之前尝试访问产品值它可以通过 API 请求获得,因此

const filteredProduct = products.filter(p => p.id == props.match.params.id)

将返回空数组。

出现此问题的原因是您尝试访问 filteredProduct[0].image 和类似的其他属性。

这里的解决方案是使用loadingState并渲染加载器直到数据可用

还要确保当数据可用时 filteredProduct 永远不会为空

export class AppProvider extends Component {
state = {
isLoading: true,
products: [],
cart: [],
dispatch: action => this.setState(state => reducer(state, action))
}

fetchData = async () => {
const products = await axios.get('http://127.0.0.1:4000/product/all', { headers: { "Access-Control-Allow-Origin": "*" } })
this.setState({
isLoading: false,
products: products.data
})
}

componentDidMount(){
this.fetchData();
}

render() {
return (
<AppContext.Provider value={this.state}>
{this.props.children}
</AppContext.Provider>
)
}
}

以及产品详细信息

const ProductDetail = props => {
const [inputValue, setInputValue] = useState(1);


const preventNegative = e => {
const value = e.target.value.replace(/[^\d]/, '');
if (parseInt(value) !== 0) {
setInputValue(value);
}
}

const addToCart = (e, productID) => {
// eslint-disable-next-line array-callback-return
const product = products.filter(p => {
// eslint-disable-next-line eqeqeq
if (p.id == productID) {
return p
}
})
console.log(product);
dispatch({
type: 'ADD_TO_CART',
payload: [product, inputValue]
})
toast.success("The product has been added to cart successfully !", {
position: toast.POSITION.TOP_CENTER,
autoClose: 2500,
transition: Slide
})
}



const { products, dispatch, isLoading } = useContext(AppContext)
if(isLoading) return <div>Loading...</div>

const filteredProduct = products.filter(p => p.id == props.match.params.id)

return (
<React.Fragment>
<main className="mt-5 pt-4">
<div className="container dark-grey-text mt-5">
<div className="row wow fadeIn">
<div className="col-md-6 mb-4">
<img src={filteredProduct[0].image} className="img-fluid" alt="" />
</div>
<div className="col-md-6 mb-4">
<div className="p-4">
<div className="mb-3">
<Badge color="primary">New</Badge>
<Badge color="success">Best seller</Badge>
<Badge color="danger">{filteredProduct[0].discountRate}% OFF</Badge>
</div>
<h2 className="h2">{filteredProduct[0].title}</h2>
<p className="lead">
<span className="mr-1">
<del>${filteredProduct[0].prevPrice}</del>
</span>
<span>${filteredProduct[0].price}</span>
</p>
<p className="text-muted">
{filteredProduct[0].detail}
</p>
<form className="d-flex justify-content-left">
<input
min="1"
onChange={(e) => preventNegative(e)}
value={inputValue}
type="number"
aria-label="Search"
className="form-control"
style={{ width: '100px' }} />

<Button onClick={(e) => addToCart(e, filteredProduct[0].id)} color="primary">Add to Cart <FontAwesomeIcon icon={faShoppingCart} /> </Button>

</form>
</div>
</div>
</div>
</div>
</main>
</React.Fragment>

)
}
export default ProductDetail;

关于javascript - Context API 中的 ReactJS 异步 axios,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61487064/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com