ReactJS101 项目实战:使用 React + Redux + Node 开发同构食谱分享网站

ReactJS101 项目实战:使用 React + Redux + Node 开发同构食谱分享网站

reactjs101 kdchang/reactjs101: 是一个关于 ReactJS 的前端开发教程项目。适合对前端开发有兴趣的人,特别是想学习 ReactJS 框架的人。特点是从基础概念和示例代码入手,逐步深入到 ReactJS 的各种高级特性,具有较强的实践性和指导性。 reactjs101 项目地址: https://gitcode.com/gh_mirrors/re/reactjs101

前言

在本教程中,我们将基于 ReactJS101 项目的知识体系,带领大家开发一个完整的同构(Isomorphic)JavaScript 应用——食谱分享网站。这个项目将整合 React、Redux、React Router 和 Node.js 等技术栈,实现前后端同构渲染、用户认证、CRUD 操作等核心功能。

项目概述

功能需求

我们将开发一个具有以下功能的食谱分享社区网站:

  1. 用户认证(登录/登出)
  2. 食谱的创建、读取、更新和删除(CRUD)
  3. 食谱列表展示
  4. 响应式设计

技术栈

  • 前端

    • React:构建用户界面
    • Redux:状态管理
    • React Router:路由控制
    • Immutable.js:不可变数据结构
    • Axios:HTTP 请求
  • 后端

    • Node.js + Express:服务器框架
    • MongoDB + Mongoose:数据库存储
    • JSON Web Token (JWT):用户认证
  • 构建工具

    • Webpack:模块打包
    • Babel:ES6/JSX 转译

项目结构设计

项目采用模块化设计,主要目录结构如下:

src/
├── client/        # 客户端代码
├── common/        # 共享代码(Redux、路由等)
├── server/        # 服务器端代码
│   ├── config/    # 配置文件
│   ├── controllers/ # API控制器
│   ├── models/    # 数据库模型

核心实现

1. 同构渲染架构

同构(Isomorphic)JavaScript 是指同一套代码可以在客户端和服务器端运行。我们的实现方案包括:

服务器端渲染流程

  1. 接收请求
  2. 获取初始数据
  3. 创建 Redux store
  4. 渲染 React 组件为字符串
  5. 注入初始状态到 HTML
  6. 发送完整 HTML 到客户端

关键代码实现

// 服务器端渲染处理函数
const handleRender = (req, res) => {
  match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
    // 获取初始数据
    fetchComponentData(req.cookies.token).then((response) => {
      const initialState = fromJS({
        recipe: { /* 初始食谱数据 */ },
        user: { /* 用户认证状态 */ }
      });
      
      // 创建 Redux store
      const store = configureStore(initialState);
      
      // 渲染组件为字符串
      const initView = renderToString(
        <Provider store={store}>
          <RouterContext {...renderProps} />
        </Provider>
      );
      
      // 注入初始状态到 HTML
      const page = renderFullPage(initView, store.getState());
      res.status(200).send(page);
    });
  });
};

2. 用户认证系统

我们采用 JWT(JSON Web Token)实现用户认证:

  1. 登录流程

    • 用户提交邮箱和密码
    • 服务器验证并生成 JWT
    • 将 token 返回给客户端存储
  2. 认证中间件

    • 对需要认证的 API 请求验证 token
    • 验证通过后允许访问受保护资源

关键代码实现

// 登录 API
apiRoutes.post('/login', (req, res) => {
  User.findOne({ email: req.body.email }, (err, user) => {
    if (!user || user.password !== req.body.password) {
      return res.json({ success: false, message: '认证失败' });
    }
    
    // 生成 JWT
    const token = jwt.sign(
      { email: user.email }, 
      app.get('superSecret'), 
      { expiresIn: '24h' }
    );
    
    res.json({ success: true, token });
  });
});

// 认证中间件
apiRoutes.use((req, res, next) => {
  const token = req.body.token || req.query.token;
  
  if (!token) {
    return res.status(403).send({ success: false, message: '未提供 token' });
  }
  
  jwt.verify(token, app.get('superSecret'), (err, decoded) => {
    if (err) return res.json({ success: false, message: 'token 验证失败' });
    req.decoded = decoded;
    next();
  });
});

3. Redux 状态管理

我们使用 Redux 管理应用状态,主要包含以下部分:

  1. Reducer 设计

    • recipeReducer:管理食谱相关状态
    • userReducer:管理用户认证状态
    • uiReducer:管理 UI 相关状态
  2. 异步 Action

    • 使用 redux-promise 中间件处理异步 API 调用
    • 通过 redux-actions 创建标准的 Flux 动作

关键代码实现

// 异步获取食谱列表
export const getRecipes = createAction('GET_RECIPES', WebAPI.getRecipes);

// 添加新食谱
export const addRecipe = createAction('ADD_RECIPE', WebAPI.addRecipe);

// 更新食谱
export const updateRecipe = createAction('UPDATE_RECIPE', WebAPI.updateRecipe);

// 删除食谱
export const deleteRecipe = createAction('DELETE_RECIPE', WebAPI.deleteRecipe);

4. 路由与权限控制

我们使用 React Router 结合高阶组件实现路由权限控制:

  1. 路由配置

    • 主路由包含首页、登录页和分享页
    • 使用 IndexRoute 设置默认路由
  2. 权限控制

    • 已登录用户不能访问登录页
    • 未登录用户不能访问分享页

关键代码实现

// 高阶组件实现权限控制
const CheckAuth = (Component, type) => {
  return class extends React.Component {
    componentWillMount() {
      this.props.checkAuth();
    }
    
    render() {
      const { isAuthorized } = this.props.user;
      
      if ((type === 'guest' && isAuthorized) || (type === 'auth' && !isAuthorized)) {
        return <Redirect to={type === 'guest' ? '/' : '/login'} />;
      }
      
      return <Component {...this.props} />;
    }
  };
};

// 路由配置
export default (
  <Route path='/' component={Main}>
    <IndexRoute component={HomePageContainer} />
    <Route path="/login" component={CheckAuth(LoginPageContainer, 'guest')}/>
    <Route path="/share" component={CheckAuth(SharePageContainer, 'auth')}/>
  </Route>
);

开发环境配置

1. 基础配置

  1. Babel 配置 (.babelrc):

    {
      "presets": ["es2015", "react"]
    }
    
  2. ESLint 配置 (.eslintrc):

    {
      "extends": "airbnb",
      "rules": {
        "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }]
      },
      "env": {
        "browser": true
      }
    }
    

2. Webpack 配置

module.exports = {
  entry: ['./src/client/index.js'],
  output: {
    path: `${__dirname}/dist`,
    filename: 'bundle.js',
    publicPath: '/static/'
  },
  module: {
    loaders: [{
      test: /\.js$/,
      exclude: /node_modules/,
      loader: 'babel-loader',
      query: {
        presets: ['es2015', 'react']
      }
    }]
  },
  plugins: [
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin()
  ]
};

数据库设计

我们使用 MongoDB 存储数据,通过 Mongoose 定义数据模型:

1. 用户模型

import mongoose, { Schema } from 'mongoose';

export default mongoose.model('User', new Schema({ 
    id: Number,
    username: String, 
    email: String,
    password: String, 
    admin: Boolean 
}));

2. 食谱模型

import mongoose, { Schema } from 'mongoose';

export default mongoose.model('Recipe', new Schema({ 
    id: String,
    name: String, 
    description: String, 
    imagePath: String,
    steps: Array,
    updatedAt: Date
}));

总结

通过本教程,我们实现了一个完整的同构 JavaScript 应用,涵盖了以下关键技术点:

  1. React + Redux 的前端架构
  2. Node.js + Express 的后端服务
  3. MongoDB 数据存储
  4. JWT 用户认证
  5. 同构渲染实现
  6. 路由权限控制

这个项目展示了如何将现代前端技术栈整合到一个实际应用中,为开发者提供了一个很好的学习范例。通过实践这个项目,你可以深入理解 React 生态系统中的各种技术和它们之间的协作方式。

reactjs101 kdchang/reactjs101: 是一个关于 ReactJS 的前端开发教程项目。适合对前端开发有兴趣的人,特别是想学习 ReactJS 框架的人。特点是从基础概念和示例代码入手,逐步深入到 ReactJS 的各种高级特性,具有较强的实践性和指导性。 reactjs101 项目地址: https://gitcode.com/gh_mirrors/re/reactjs101

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

田鲁焘Gilbert

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值