MST
星途 面试题库

面试题:React动态增删列表项与复杂业务逻辑的融合处理

在一个电商订单管理系统的React前端项目中,订单列表需要支持动态增删子订单项(每个子订单项包含商品信息、数量、价格等复杂数据结构),同时增删操作要触发库存更新、总价计算等复杂业务逻辑,并且要与后端进行实时交互确保数据一致性。请详细设计整体架构方案,并说明如何保证系统的稳定性、可靠性以及高并发情况下的处理策略。
43.4万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

整体架构方案

1. 前端架构

  • 组件设计
    • 创建 OrderList 组件用于展示订单列表,该组件包含 SubOrderItem 子组件。SubOrderItem 组件负责展示单个子订单项的商品信息、数量、价格等,并提供增删操作按钮。
    • 例如,SubOrderItem 组件结构如下:
import React from'react';

const SubOrderItem = ({ item, onDelete, onQuantityChange }) => {
    const { productInfo, quantity, price } = item;
    return (
        <div>
            <p>{productInfo}</p>
            <input type="number" value={quantity} onChange={onQuantityChange} />
            <p>Price: {price}</p>
            <button onClick={onDelete}>Delete</button>
        </div>
    );
};

export default SubOrderItem;
- `OrderList` 组件维护子订单项的状态数组,通过 `map` 方法渲染多个 `SubOrderItem`。
import React, { useState } from'react';
import SubOrderItem from './SubOrderItem';

const OrderList = () => {
    const [subOrderItems, setSubOrderItems] = useState([]);

    const addSubOrderItem = (newItem) => {
        setSubOrderItems([...subOrderItems, newItem]);
    };

    const deleteSubOrderItem = (index) => {
        const newItems = [...subOrderItems];
        newItems.splice(index, 1);
        setSubOrderItems(newItems);
    };

    const handleQuantityChange = (index, newQuantity) => {
        const newItems = [...subOrderItems];
        newItems[index].quantity = newQuantity;
        setSubOrderItems(newItems);
    };

    return (
        <div>
            {subOrderItems.map((item, index) => (
                <SubOrderItem
                    key={index}
                    item={item}
                    onDelete={() => deleteSubOrderItem(index)}
                    onQuantityChange={(e) => handleQuantityChange(index, parseInt(e.target.value))}
                />
            ))}
            <button onClick={() => addSubOrderItem({ /* 新子订单项初始数据 */ })}>Add Item</button>
        </div>
    );
};

export default OrderList;
  • 状态管理:使用 React 的 useStateuseReducer 管理子订单项的状态。对于复杂业务逻辑,可引入 Redux 或 MobX 进行状态管理,便于集中处理状态变化和业务逻辑。例如,使用 Redux 时,创建 order slice 来管理订单相关状态:
import { createSlice } from '@reduxjs/toolkit';

const orderSlice = createSlice({
    name: 'order',
    initialState: {
        subOrderItems: []
    },
    reducers: {
        addSubOrderItem: (state, action) => {
            state.subOrderItems.push(action.payload);
        },
        deleteSubOrderItem: (state, action) => {
            state.subOrderItems = state.subOrderItems.filter((_, index) => index!== action.payload);
        },
        updateQuantity: (state, action) => {
            const { index, newQuantity } = action.payload;
            state.subOrderItems[index].quantity = newQuantity;
        }
    }
});

export const { addSubOrderItem, deleteSubOrderItem, updateQuantity } = orderSlice.actions;
export default orderSlice.reducer;
  • 业务逻辑处理:在增删子订单项的回调函数中触发库存更新、总价计算等业务逻辑。例如,计算总价的函数:
const calculateTotalPrice = (subOrderItems) => {
    return subOrderItems.reduce((total, item) => total + item.quantity * item.price, 0);
};

OrderList 组件中,可在状态更新后调用此函数:

import React, { useState, useEffect } from'react';
import { useSelector } from'react-redux';

const OrderList = () => {
    const subOrderItems = useSelector((state) => state.order.subOrderItems);
    const [totalPrice, setTotalPrice] = useState(0);

    useEffect(() => {
        const newTotal = calculateTotalPrice(subOrderItems);
        setTotalPrice(newTotal);
    }, [subOrderItems]);

    return (
        <div>
            {/* 子订单项渲染 */}
            <p>Total Price: {totalPrice}</p>
        </div>
    );
};

export default OrderList;

2. 后端架构

  • API 设计
    • 提供添加子订单项的 API,如 POST /orders/{orderId}/subItems,接收子订单项数据并保存到数据库,同时触发库存更新逻辑。
    • 提供删除子订单项的 API,如 DELETE /orders/{orderId}/subItems/{subItemId},删除数据库中的子订单项记录,并相应更新库存。
    • 提供获取订单详情的 API,如 GET /orders/{orderId},用于前端初始化订单列表数据。
  • 数据库设计:使用关系型数据库(如 MySQL),设计 orders 表存储订单主信息,sub_order_items 表存储子订单项信息,products 表存储商品信息及库存。通过外键关联 orderssub_order_itemssub_order_itemsproducts
  • 库存更新与事务处理:在增删子订单项的 API 处理中,使用数据库事务确保库存更新与订单数据操作的一致性。例如,在添加子订单项时:
from flask import Flask, request
from flask_sqlalchemy import SQLAlchemy
import json

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] ='mysql://user:password@localhost/your_database'
db = SQLAlchemy(app)

class Order(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    sub_order_items = db.relationship('SubOrderItem', backref='order')

class SubOrderItem(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    order_id = db.Column(db.Integer, db.ForeignKey('order.id'))
    product_id = db.Column(db.Integer, db.ForeignKey('product.id'))
    quantity = db.Column(db.Integer)

class Product(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    stock = db.Column(db.Integer)

@app.route('/orders/<int:orderId>/subItems', methods=['POST'])
def add_sub_order_item(orderId):
    data = request.get_json()
    product_id = data['product_id']
    quantity = data['quantity']

    try:
        db.session.begin()
        new_sub_item = SubOrderItem(order_id=orderId, product_id=product_id, quantity=quantity)
        db.session.add(new_sub_item)

        product = Product.query.get(product_id)
        product.stock -= quantity
        db.session.commit()
        return json.dumps({'message': 'Sub - order item added successfully'}), 200
    except Exception as e:
        db.session.rollback()
        return json.dumps({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True)

保证系统稳定性和可靠性

1. 前端方面

  • 数据验证:在用户输入子订单项数据(如数量)时,进行严格的数据验证,确保输入合法。例如,使用正则表达式验证数量是否为正整数:
const validateQuantity = (quantity) => {
    return /^\d+$/.test(quantity) && parseInt(quantity) > 0;
};
  • 错误处理:在调用后端 API 时,使用 try - catch 捕获异常,友好提示用户错误信息。例如:
const addSubOrderItem = async (newItem) => {
    try {
        const response = await fetch('/orders/{orderId}/subItems', {
            method: 'POST',
            headers: {
                'Content - Type': 'application/json'
            },
            body: JSON.stringify(newItem)
        });
        if (response.ok) {
            setSubOrderItems([...subOrderItems, newItem]);
        } else {
            throw new Error('Failed to add sub - order item');
        }
    } catch (error) {
        console.error(error);
        alert('An error occurred while adding the sub - order item.');
    }
};

2. 后端方面

  • 输入验证:在 API 接口接收数据时,同样进行严格的输入验证,防止非法数据进入系统。例如,在 Flask 应用中使用 wtforms 进行表单验证:
from wtforms import Form, IntegerField, validators

class AddSubOrderItemForm(Form):
    product_id = IntegerField('Product ID', [validators.DataRequired()])
    quantity = IntegerField('Quantity', [validators.DataRequired(), validators.NumberRange(min = 1)])
  • 日志记录:使用日志记录系统记录关键操作和错误信息,便于排查问题。例如,在 Python 中使用 logging 模块:
import logging

logging.basicConfig(filename='app.log', level = logging.INFO,
                    format='%(asctime)s - %(levelname)s - %(message)s')

@app.route('/orders/<int:orderId>/subItems', methods=['POST'])
def add_sub_order_item(orderId):
    try:
        form = AddSubOrderItemForm(request.form)
        if form.validate():
            # 处理业务逻辑
            logging.info('Sub - order item added successfully for order %d', orderId)
            return json.dumps({'message': 'Sub - order item added successfully'}), 200
        else:
            logging.warning('Invalid data for adding sub - order item for order %d', orderId)
            return json.dumps({'error': 'Invalid data'}), 400
    except Exception as e:
        logging.error('Error adding sub - order item for order %d: %s', orderId, str(e))
        return json.dumps({'error': str(e)}), 500
  • 系统监控:部署监控工具(如 Prometheus + Grafana)监控后端服务的各项指标,如 CPU 使用率、内存使用率、API 响应时间等,及时发现性能问题和异常。

高并发情况下的处理策略

1. 前端方面

  • 节流与防抖:对于频繁触发的操作(如连续点击添加子订单项按钮),使用节流(throttle)或防抖(debounce)技术限制操作频率,减轻后端压力。例如,使用 Lodash 的 debounce 函数处理输入框数量变化事件:
import debounce from 'lodash/debounce';

const handleQuantityChange = debounce((index, newQuantity) => {
    // 处理数量变化逻辑
}, 300);

2. 后端方面

  • 缓存机制:使用缓存(如 Redis)缓存经常访问的数据,如订单列表数据、商品信息等。在高并发情况下,优先从缓存获取数据,减少数据库压力。例如,在获取订单详情 API 中:
import redis
from flask import Flask, jsonify

app = Flask(__name__)
redis_client = redis.StrictRedis(host='localhost', port = 6379, db = 0)

@app.route('/orders/<int:orderId>')
def get_order(orderId):
    order_data = redis_client.get(f'order:{orderId}')
    if order_data:
        return jsonify(json.loads(order_data))

    # 从数据库获取数据
    order = Order.query.get(orderId)
    if order:
        order_dict = {
            'id': order.id,
          'sub_order_items': [
                {
                    'id': sub_item.id,
                    'product_id': sub_item.product_id,
                    'quantity': sub_item.quantity
                } for sub_item in order.sub_order_items
            ]
        }
        redis_client.setex(f'order:{orderId}', 3600, json.dumps(order_dict))
        return jsonify(order_dict)
    else:
        return jsonify({'message': 'Order not found'}), 404
  • 负载均衡:部署负载均衡器(如 Nginx)将高并发请求均匀分配到多个后端服务器实例上,提高系统的并发处理能力。
  • 数据库优化
    • 索引优化:为数据库表的常用查询字段添加索引,如 orders 表的 orderId 字段,sub_order_items 表的 order_idproduct_id 字段等,加快查询速度。
    • 读写分离:对于读多写少的场景,采用读写分离架构,将读操作分发到从数据库,减轻主数据库的压力。