You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React应用中调用自建Node.js+Express+MongoDB API路由

Hey there! Let's work through getting your React e-commerce app talking to your custom API smoothly. Since you’ve confirmed the API works perfectly in Postman, the issue is almost certainly in how React is structuring requests or a small configuration gap. Here’s a step-by-step breakdown to fix this:

1. First: Fix CORS (Cross-Origin Resource Sharing)

This is the most common culprit when local React apps can’t talk to local APIs. React runs on localhost:3000 by default, while your Express API is likely on a different port (like 5000). Browsers block cross-origin requests unless the API explicitly allows them.

To fix this:

  • Install the cors package in your Express project:
    npm install cors
    
  • Add it to your Express app setup:
    // In your Express server file (e.g., server.js)
    const cors = require('cors');
    const app = express();
    
    // Allow all origins (for development only; lock this down in production!)
    app.use(cors());
    
    // Or restrict to your React app's origin for better security:
    // app.use(cors({ origin: 'http://localhost:3000' }));
    
2. Use a Consistent API Base URL

Stop using relative paths (like /api/products) in React—they’ll point to React’s port (3000) instead of your API’s port. Create a reusable utility file to manage your API endpoints:

// src/utils/api.js
// Replace with your actual API port and base path
const BASE_API_URL = 'http://localhost:5000/api';

// Helper function for GET requests
export const fetchProducts = async () => {
  const response = await fetch(`${BASE_API_URL}/products`);
  // Always check if the response is successful first!
  if (!response.ok) throw new Error(`Failed to fetch: ${response.statusText}`);
  return response.json();
};

For production, store this URL in a .env file (React automatically picks up variables prefixed with REACT_APP_):

# .env file in your React project root
REACT_APP_API_URL=http://your-production-api-url.com/api

Then update your utility file:

const BASE_API_URL = process.env.REACT_APP_API_URL;
3. Implement CRUD Operations in React

Here’s how to map each CRUD action to your API, with error handling:

Read (Fetch Products)

Use useEffect to load data when your component mounts:

// src/components/ProductList.js
import { useState, useEffect } from 'react';
import { fetchProducts } from '../utils/api';

function ProductList() {
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const loadProducts = async () => {
      try {
        const data = await fetchProducts();
        setProducts(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };
    loadProducts();
  }, []);

  if (loading) return <div>Loading products...</div>;
  if (error) return <div className="error">Oops: {error}</div>;

  return (
    <div className="product-grid">
      {products.map(product => (
        <div key={product._id} className="product-card">
          <h3>{product.name}</h3>
          <p>${product.price}</p>
        </div>
      ))}
    </div>
  );
}

export default ProductList;

Create (Add a Product)

Handle form submissions with a POST request:

// Add to src/utils/api.js
export const createProduct = async (productData) => {
  const response = await fetch(`${BASE_API_URL}/products`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(productData),
  });
  if (!response.ok) throw new Error('Failed to create product');
  return response.json();
};

// In your AddProduct component
const handleSubmit = async (e) => {
  e.preventDefault();
  try {
    const newProduct = await createProduct({ name, price, description });
    // Update local state to show the new product immediately
    setProducts(prev => [...prev, newProduct]);
    // Reset form
    setName('');
    setPrice('');
    setDescription('');
  } catch (err) {
    setError(err.message);
  }
};

Update (Edit a Product)

Use a PUT request with the product ID:

// Add to src/utils/api.js
export const updateProduct = async (productId, updatedData) => {
  const response = await fetch(`${BASE_API_URL}/products/${productId}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(updatedData),
  });
  if (!response.ok) throw new Error('Failed to update product');
  return response.json();
};

Delete (Remove a Product)

Use a DELETE request:

// Add to src/utils/api.js
export const deleteProduct = async (productId) => {
  const response = await fetch(`${BASE_API_URL}/products/${productId}`, {
    method: 'DELETE',
  });
  if (!response.ok) throw new Error('Failed to delete product');
};

// In your ProductList component
const handleDelete = async (productId) => {
  try {
    await deleteProduct(productId);
    // Update local state to remove the deleted product
    setProducts(prev => prev.filter(p => p._id !== productId));
  } catch (err) {
    setError(err.message);
  }
};
4. Debug with Browser DevTools

If something still isn’t working:

  • Open your browser’s Network tab (F12 > Network)
  • Compare the request details (method, headers, body) to what you sent in Postman
  • Look for error status codes (4xx = client error, 5xx = server error) and check the response body for clues
Final Checks
  • Make sure your Express API is running when you start your React app
  • Double-check that your API routes match exactly what you’re calling in React (e.g., /api/products vs /products)
  • Ensure MongoDB is connected and your API is correctly reading/writing to the database

内容的提问来源于stack exchange,提问作者VColson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:10:25