前言
在当今数字化时代,电商应用已经成为了许多企业的重要业务之一。而作为一名前端开发者,我们需要掌握一些全栈技能,以便更好地构建电商应用。
本文将介绍如何使用 Next.js 和 Redux 构建一个全栈电商应用。我们将从基础开始,逐步深入,最终构建一个完整的电商应用。
技术栈
- Next.js:一个基于 React 的服务端渲染框架,可以让我们快速构建高性能的应用。
- Redux:一个状态管理库,可以让我们更好地管理应用的状态。
- MongoDB:一种流行的 NoSQL 数据库,可以让我们轻松存储和查询数据。
- Express:一个 Node.js 的框架,可以让我们构建 Web 应用。
前置知识
- React:一个流行的前端框架。
- Node.js:一个基于 Chrome V8 引擎的 JavaScript 运行时。
- JavaScript:一种流行的脚本语言。
准备工作
在开始之前,我们需要安装 Node.js 和 MongoDB。你可以在官网上下载并安装它们。
接下来,我们需要创建一个空的 Next.js 应用。你可以使用以下命令创建一个名为 "ecommerce" 的应用:
npx create-next-app ecommerce
然后,我们需要安装一些必要的依赖项。你可以使用以下命令安装它们:
cd ecommerce npm install --save next react react-dom redux react-redux redux-thunk axios mongoose express body-parser cors
构建前端
首先,我们需要构建前端。在 Next.js 中,我们可以创建一个名为 "pages" 的文件夹。在该文件夹中,我们可以创建一个名为 "index.js" 的文件,作为我们的首页。
在 "index.js" 文件中,我们可以使用 React 编写我们的 UI。在这个例子中,我们将展示一些电商产品,并使用 Redux 来管理状态。
// javascriptcn.com 代码示例 import React from 'react'; import { connect } from 'react-redux'; import { fetchProducts } from '../redux/actions'; class Home extends React.Component { componentDidMount() { this.props.fetchProducts(); } render() { const { products } = this.props; return ( <div> <h1>Products</h1> <ul> {products.map(product => ( <li key={product._id}> <h2>{product.name}</h2> <p>{product.description}</p> <p>{product.price}</p> </li> ))} </ul> </div> ); } } const mapStateToProps = state => ({ products: state.products, }); export default connect(mapStateToProps, { fetchProducts })(Home);
在上面的代码中,我们首先导入了 React 和 connect 函数(来自 react-redux 库)。然后,我们定义了一个名为 "Home" 的组件,并将它连接到 Redux store。
在组件的 componentDidMount 方法中,我们调用了 fetchProducts 函数,该函数将从后端 API 获取产品列表,并将它们存储在 Redux store 中。
在组件的 render 方法中,我们使用 map 函数遍历产品列表,并展示它们的名称、描述和价格。
现在,我们需要定义 Redux store 和相关的 actions 和 reducers。我们可以在 "redux" 文件夹中创建一个名为 "store.js" 的文件,定义我们的 Redux store。
// javascriptcn.com 代码示例 import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import axios from 'axios'; const initialState = { products: [], }; export const actionTypes = { FETCH_PRODUCTS: 'FETCH_PRODUCTS', }; export const fetchProducts = () => async dispatch => { const res = await axios.get('/api/products'); dispatch({ type: actionTypes.FETCH_PRODUCTS, payload: res.data }); }; export const reducer = (state = initialState, action) => { switch (action.type) { case actionTypes.FETCH_PRODUCTS: return { ...state, products: action.payload }; default: return state; } }; export const initStore = (state = initialState) => { return createStore(reducer, state, applyMiddleware(thunk)); };
在上面的代码中,我们首先定义了一个名为 "initialState" 的对象,它包含了我们的应用状态。然后,我们定义了一个名为 "actionTypes" 的对象,它包含了我们的 action 类型。
接下来,我们定义了一个名为 "fetchProducts" 的函数,它使用 axios 库从后端 API 获取产品列表,并将它们存储在 Redux store 中。
最后,我们定义了一个名为 "reducer" 的函数,它接收一个状态和一个 action,并根据 action 的类型更新状态。我们还定义了一个名为 "initStore" 的函数,它创建了我们的 Redux store。
现在,我们需要将 Redux store 注入到我们的应用中。我们可以在 "pages" 文件夹中创建一个名为 "store.js" 的文件,导出一个名为 "wrapper" 的函数。
// javascriptcn.com 代码示例 import { Provider } from 'react-redux'; import { initStore } from '../redux/store'; const wrapper = Page => { const store = initStore(); return () => ( <Provider store={store}> <Page /> </Provider> ); }; export default wrapper;
在上面的代码中,我们首先导入了 Provider 组件(来自 react-redux 库)和 initStore 函数。然后,我们定义了一个名为 "wrapper" 的函数,它接收一个页面组件作为参数,并返回一个函数。
在返回的函数中,我们创建了 Redux store,并将它作为 props 传递给 Provider 组件。然后,我们将页面组件作为 Provider 的子组件返回。
现在,我们可以在 "index.js" 文件中导入 "wrapper" 函数,并使用它来包装我们的 "Home" 组件。
import wrapper from './store'; import Home from './Home'; export default wrapper(Home);
现在,我们的前端已经完成了。我们可以使用以下命令启动它:
npm run dev
构建后端
接下来,我们需要构建后端。在 Node.js 中,我们可以使用 Express 框架来构建 Web 应用。我们可以在 "server.js" 文件中创建一个名为 "app" 的 Express 应用。
// javascriptcn.com 代码示例 const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const mongoose = require('mongoose'); const app = express(); app.use(bodyParser.json()); app.use(cors()); mongoose.connect('mongodb://localhost/ecommerce', { useNewUrlParser: true, useUnifiedTopology: true }); const Product = mongoose.model('Product', { name: String, description: String, price: Number, }); app.get('/api/products', async (req, res) => { const products = await Product.find(); res.json(products); }); app.post('/api/products', async (req, res) => { const { name, description, price } = req.body; const product = new Product({ name, description, price }); await product.save(); res.json(product); }); app.listen(3001, () => console.log('Server started'));
在上面的代码中,我们首先导入了 Express、body-parser、cors 和 mongoose 库。然后,我们定义了一个名为 "app" 的 Express 应用,并使用 bodyParser 和 cors 中间件。
接下来,我们连接到 MongoDB 数据库,并定义了一个名为 "Product" 的模型,它代表了我们的产品。
在 app.get('/api/products') 路由中,我们使用 Product.find 方法从数据库中获取所有产品,并将它们作为 JSON 格式返回。
在 app.post('/api/products') 路由中,我们从请求体中获取产品的名称、描述和价格,并使用 Product.save 方法将它们存储到数据库中。最后,我们将产品作为 JSON 格式返回。
现在,我们需要修改前端代码,以便它可以与后端 API 进行交互。我们可以在 "redux" 文件夹中的 "actions.js" 文件中创建一个名为 "createProduct" 的函数,它将产品数据发送到后端 API。
import axios from 'axios'; export const createProduct = product => async dispatch => { const res = await axios.post('/api/products', product); dispatch(fetchProducts()); return res.data; };
在上面的代码中,我们首先导入了 axios 库。然后,我们定义了一个名为 "createProduct" 的函数,它使用 axios 库将产品数据发送到后端 API,并在成功后调用 fetchProducts 函数更新产品列表。
现在,我们需要在 "Home" 组件中添加一个表单,以便用户可以创建新产品。我们可以在 "Home" 组件中添加一个名为 "handleSubmit" 的方法,并在提交表单时调用它。
// javascriptcn.com 代码示例 import React from 'react'; import { connect } from 'react-redux'; import { fetchProducts, createProduct } from '../redux/actions'; class Home extends React.Component { state = { name: '', description: '', price: '', }; componentDidMount() { this.props.fetchProducts(); } handleChange = e => { this.setState({ [e.target.name]: e.target.value }); }; handleSubmit = e => { e.preventDefault(); const { name, description, price } = this.state; this.props.createProduct({ name, description, price }); this.setState({ name: '', description: '', price: '' }); }; render() { const { products } = this.props; const { name, description, price } = this.state; return ( <div> <h1>Products</h1> <ul> {products.map(product => ( <li key={product._id}> <h2>{product.name}</h2> <p>{product.description}</p> <p>{product.price}</p> </li> ))} </ul> <form onSubmit={this.handleSubmit}> <input type="text" name="name" value={name} onChange={this.handleChange} /> <input type="text" name="description" value={description} onChange={this.handleChange} /> <input type="text" name="price" value={price} onChange={this.handleChange} /> <button type="submit">Add Product</button> </form> </div> ); } } const mapStateToProps = state => ({ products: state.products, }); export default connect(mapStateToProps, { fetchProducts, createProduct })(Home);
在上面的代码中,我们首先定义了一个名为 "state" 的对象,它包含了表单的名称、描述和价格。然后,我们定义了一个名为 "handleChange" 的方法,它在用户输入时更新表单的状态。
在 handleSubmit 方法中,我们首先阻止表单的默认行为。然后,我们从状态中获取产品的名称、描述和价格,并将它们作为参数传递给 createProduct 函数。最后,我们重置表单状态。
现在,我们可以使用以下命令来启动我们的应用:
npm run dev
总结
在本文中,我们介绍了如何使用 Next.js 和 Redux 构建一个全栈电商应用。我们首先构建了前端,使用 React 和 Redux 来展示电商产品。然后,我们构建了后端,使用 Express 和 MongoDB 来存储和查询产品数据。最后,我们将前端和后端连接起来,以便用户可以创建和展示产品。
通过本文的学习,我们可以更好地理解全栈开发的概念,并掌握构建全栈应用的技能。希望本文对你有所帮助。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6574ee33d2f5e1655de13ce6