如何整合React与Express?前后端项目合并问题咨询
Hey there! Let’s break down how to get your front-end and back-end working together seamlessly—your initial hunch is spot-on, so let’s turn that into actionable steps.
You’re right to shift toward using your Node/Express backend as a data provider for your React front-end. Instead of having the backend render Jade views directly, it will expose JSON APIs that your React app calls to fetch and manipulate data. This way, your React app becomes the single "view layer" for your entire application.
1. Refactor Backend to Serve APIs (Instead of Jade Views)
First, let’s convert your existing database logic into API endpoints that return JSON data, and fix cross-origin issues since your front-end is on port 3000 and backend on 3001.
Add CORS Support
Browsers block cross-origin requests by default, so install the cors package to allow communication between ports:
npm install cors
Then configure it in your server.js:
const cors = require('cors'); app.use(cors()); // For development; restrict to your front-end domain in production
Replace Jade Routes with API Endpoints
Instead of rendering a Jade view, return JSON data from your database queries. For example:
// Old: Rendering Jade view app.get('/show-data', (req, res) => { db.query('SELECT * FROM your_table', (err, results) => { if (err) throw err; res.render('data-page', { data: results }); }); }); // New: API endpoint returning JSON app.get('/api/data', (req, res) => { db.query('SELECT * FROM your_table', (err, results) => { if (err) { res.status(500).json({ error: err.message }); return; } res.json(results); }); });
Add an API for Adding List Items
Since your front-end can already add items locally, connect that action to a backend API to persist data to MySQL:
app.post('/api/add-item', (req, res) => { const { itemContent } = req.body; // Match the data your front-end sends const query = 'INSERT INTO your_table (content) VALUES (?)'; db.query(query, [itemContent], (err, result) => { if (err) { res.status(500).json({ error: err.message }); return; } // Return the newly created item (including its auto-generated ID) res.json({ id: result.insertId, content: itemContent }); }); });
2. Update Front-End to Call Backend APIs
Now, modify your React/Redux code to fetch data from the backend and send new items to be saved.
Fetch Data on Component Load
Use fetch or Axios to pull data from your backend API when your React component mounts, then update your Redux store:
// Example with fetch in a React component import { useEffect } from 'react'; import { useDispatch } from 'react-redux'; import { setListData } from './redux/actions'; function ListComponent() { const dispatch = useDispatch(); useEffect(() => { const fetchData = async () => { try { const response = await fetch('http://localhost:3001/api/data'); const data = await response.json(); dispatch(setListData(data)); // Update Redux store with fetched data } catch (err) { console.error('Failed to load list data:', err); } }; fetchData(); }, [dispatch]); // Rest of your component logic... }
Send New Items to the Backend
Update your "add item" handler to send the new item to the backend API, then update your Redux store with the saved item:
const handleAddItem = async (newItemContent) => { try { const response = await fetch('http://localhost:3001/api/add-item', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ itemContent: newItemContent }), }); const savedItem = await response.json(); dispatch(addItemToList(savedItem)); // Update Redux store with the persisted item } catch (err) { console.error('Failed to save item:', err); } };
3. (Optional) Unify Ports for Production
For production, you can serve your built React files directly from your Express backend, so you only need one port:
- Build your front-end with
npm run build(this creates abuildfolder with static files) - Add static file serving to your
server.js:
const path = require('path'); // Serve React's built files app.use(express.static(path.join(__dirname, '../client/build'))); // Catch all other routes and return React's index.html (for SPA routing) app.get('*', (req, res) => { res.sendFile(path.join(__dirname, '../client/build/index.html')); });
Now, accessing http://localhost:3001 will load your React app, and API requests can use relative paths like /api/data instead of full URLs.
This setup will merge your two separate pages into a single, cohesive application where the front-end handles all UI interactions and the backend manages database operations and data persistence.
内容的提问来源于stack exchange,提问作者jelte

