我对 React 比较陌生,在读取本地 JSON 文件时遇到问题。奇怪的是,当我尝试从 API 读取数据时,一切都工作得很好。有人可以帮助我了解可能导致这种差异的原因以及如何解决它吗?
下面,我提供了我的代码片段以及相应的 StackBlitz 示例以供参考。
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import '../App.css';
import Photos from '../data/photos.json';
// import './App.css';
import { Link, useNavigate } from 'react-router-dom'; // Assuming you're using React Router
const ProductListing = () => {
const [products, setProducts] = useState([]);
const [filteredProducts, setFilteredProducts] = useState([]); // State for search results
const navigate = useNavigate(); // Import useNavigate hook
const [cart, setCart] = useState(() => {
// Load existing cart from localStorage
const storedCart = localStorage.getItem('cart');
return storedCart ? JSON.parse(storedCart) : [];
});
const addToCart = (product) => {
const newCart = [...cart, product];
setCart(newCart);
localStorage.setItem('cart', JSON.stringify(newCart)); // Store updated cart
};
const [error, setError] = useState(null);
const [currentPage, setCurrentPage] = useState(1);
const productsPerPage = 50;
const [searchTerm, setSearchTerm] = useState(''); // Search state
useEffect(() => {
const fetchProducts = async () => {
try {
const response = await axios.get('./data/photos.json');
setProducts(response.data);
setFilteredProducts(response.data); // Initialize filtered products
} catch (error) {
setError(error);
}
};
fetchProducts();
}, []); // Calculate indices for slicing the array
// Handle search input changes
const handleSearchChange = (event) => {
setSearchTerm(event.target.value);
};
// Perform search filtering when the search term changes
useEffect(() => {
const newFilteredProducts = products.filter((product) =>
product.title.toLowerCase().includes(searchTerm.toLowerCase())
);
setFilteredProducts(newFilteredProducts);
setCurrentPage(1); // Reset pagination when search changes
}, [searchTerm, products]);
// Calculations for pagination (using filteredProducts)
const indexOfLastProduct = currentPage * productsPerPage;
const indexOfFirstProduct = indexOfLastProduct - productsPerPage;
const currentProducts = filteredProducts.slice(
indexOfFirstProduct,
indexOfLastProduct
);
// const indexOfLastProduct = currentPage * productsPerPage;
// const indexOfFirstProduct = indexOfLastProduct - productsPerPage;
// const currentProducts = products.slice(
// indexOfFirstProduct,
// indexOfLastProduct
// );
const handlePageChange = (pageNumber) => {
setCurrentPage(pageNumber);
};
const renderPagination = () => {
const pageNumbers = [];
for (let i = 1; i <= Math.ceil(products.length / productsPerPage); i++) {
pageNumbers.push(i);
}
return (
<nav>
<ul className="pagination">
{pageNumbers.map((number) => (
<li
key={number}
className={
currentPage === number ? 'page-item active' : 'page-item'
}
>
<a
onClick={() => handlePageChange(number)}
href="#"
className="page-link"
>
{number}
</a>
</li>
))}
</ul>
</nav>
);
};
return (
<div className="product-container">
<input
type="text"
placeholder="Search..."
value={searchTerm}
onChange={handleSearchChange}
className="search-input"
/>
{error ? (
<p className="error-message">Error fetching products</p>
) : (
<>
{/* Added for pagination container */}
<div className="product-grid">
{currentProducts.map((product) => (
<div className="product-item" key={product.id}>
{/* {product.id} */}
<img
src={product.thumbnailUrl}
alt={product.title}
style={{ width: '50px', marginRight: '10px' }}
className="product-image"
onClick={() => navigate(`/reviews/${product.id}`)} // Navigate to review page
/>
<p className="product-id">{product.id}</p>
<button onClick={() => addToCart(product)}>Add to Cart</button>
</div>
))}
</div>
{renderPagination()}
<Link to="/checkout" className="checkout-button">
Go to Checkout
</Link>
</>
)}
</div>
);
};
export default ProductListing;
您正在使用该文件,还是仍在发出 API 请求?您可以在此处从项目导入 JSON 数据:
import Photos from '../data/photos.json';
但你从不使用它。相反,您尝试在此处通过 AJAX 获取它:
const response = await axios.get('./data/photos.json');
但是,此文件不作为应用程序结果输出的一部分托管。所以服务器返回的是 HTML。 (也许是404页面,也许是应用程序的主页等等)
由于您已经导入了所需的数据,因此无需发出 AJAX 请求来获取相同的数据。您可以完全删除
useEffect
的 fetchProducts
并将状态值初始化为导入的数据:
const [products, setProducts] = useState(Photos]);
const [filteredProducts, setFilteredProducts] = useState(Photos);