React基础框架搭建6-添加业务模块示例(用于做一些示例/demo):react+router+redux+axios+Tailwind+webpack

1、创建用户认证模块

创建目录:

在 src/features/ 目录下创建一个新的文件夹 Auth:

在Auth文件夹下创建状态切片 authSlice.js

复制代码
//src/features/Produc/producSlice.js

import { createSlice } from '@reduxjs/toolkit';

const productSlice = createSlice({
    name: 'product',
    initialState: {
        products: [], // 存储产品列表
    },
    reducers: {
        setProducts: (state, action) => {
            state.products = action.payload; // 设置产品列表
        },
        addProduct: (state, action) => {
            state.products.push(action.payload); // 添加新产品
        },
        removeProduct: (state, action) => {
            state.products = state.products.filter(product => product.id !== action.payload); // 根据 ID 移除产品
        },
    },
});

// 导出 actions
export const { setProducts, addProduct, removeProduct } = productSlice.actions;

// 导出 reducer
export default productSlice.reducer;

更新 Redux Store:

复制代码
//src/store/index.js

import { configureStore } from '@reduxjs/toolkit';
import authReducer from './authSlice';
import productReducer from '../features/Product/productSlice'; // 引入 Product 切片

const store = configureStore({
    reducer: {
        auth: authReducer,
        product: productReducer, // 添加 Product 切片
    },
});

export default store;

安装 React Hook Form:

复制代码
 npm install react-hook-form

创建反馈表单组件:

创建文件: src/views/Product/FeedbackForm.jsx

复制代码
// src/views/Product/FeedbackForm.jsx 
import React from 'react';
import { useForm } from 'react-hook-form';
import { useDispatch } from 'react-redux';
import { addProduct } from '../../features/Product/productSlice';

const FeedbackForm = () => {
    const { register, handleSubmit } = useForm();
    const dispatch = useDispatch();

    const onSubmit = (data) => {
        console.log(data);
        alert('反馈提交成功!');

        const newProduct = { id: Date.now(), name: data.feedback };
        dispatch(addProduct(newProduct));
    };

    return (
        <form onSubmit={handleSubmit(onSubmit)} className="mb-4">
            <textarea
                {...register('feedback')}
                placeholder="请输入您的反馈"
                required
                className="border border-gray-300 p-2 w-full h-24 rounded mb-2"
            />
            <button type="submit" className="px-4 py-2 bg-blue-500 text-white rounded">提交获取反馈</button>
        </form>
    );
};

export default FeedbackForm; 

创建文件: src/views/Product/ProductList.jsx

复制代码
// src/views/Product/Product.jsx 

import React from 'react';
import { useSelector } from 'react-redux';

const ProductList = () => {
    const products = useSelector((state) => state.product.products); // 获取产品列表

    return (
        <div className="mt-10">
            <h2 className="font-semibold">产品列表</h2>
            <ul className="list-disc pl-5">
                {products.length > 0 ? (
                    products.map(product => (
                        <li key={product.id} className="mb-1">{product.name}</li>
                    ))
                ) : (
                    <li>没有产品可显示</li>
                )}
            </ul>
        </div>
    );
};

export default ProductList;

在产品页面中使用表单和查看列表:

在 src/views/Product/ProductList.jsx 中引入并使用 ProductList和FeedbackForm 组件:

复制代码
// src/views/Product/ProductList.jsx 

import React from 'react';
import FeedbackForm from './FeedbackForm';
import ProductList from './ProductList';

const Product = () => {
    return (
        <div className="p-10">
            <h2 className="font-semibold">添加</h2>
            <FeedbackForm />
            <ProductList />
        </div>
    );
};

export default Product; 

查看:

添加路由:

复制代码
import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Home from '../views/Home/Home';
import About from '../views/About/About';
import Product from '../views/Product/Product';

const AppRouter = () => {
    return (
        <Router>
            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/about" element={<About />} />
                <Route path="/product" element={<Product />} />
                {/* 其他路由 */}
            </Routes>
        </Router>
    );
};

export default AppRouter;

Home添加链接:

复制代码
import React from 'react';
import { Link } from 'react-router-dom';

const Home = () => {
    return (
        <div className="flex flex-col items-center justify-center h-screen">
            <h1 className="text-4xl font-bold">欢迎来到 ReactBase 框架</h1>
            <p className="mt-4 text-lg">这是一个基于 React 的前端框架示例。</p>
            <br />
            <Link to="/about">
                <button className="mt-4 px-4 py-2 bg-blue-500 text-white rounded">前往关于页面</button>
            </Link>
            <Link to="/product">
                <button className="mt-4 px-4 py-2 bg-blue-500 text-white rounded">产品表单</button>
            </Link>
        </div>
    );
};

export default Home;

2、测试

在 src/views/Home中创建__tests__文件夹,并创建Home.test.js文件

复制代码
//src/views/Home/__tests__/Home.test.js

import React from 'react';
import { render, screen } from '@testing-library/react';
import Home from '../Home';

test('renders welcome message', () => {
    render(<Home />);
    const linkElement = screen.getByText(/欢迎来到 ReactBase 框架/i);
    expect(linkElement).toBeInTheDocument();
}); 
相关推荐
清山博客19 小时前
OpenCV 人脸识别和比对工具
前端·webpack·node.js
要加油哦~19 小时前
AI | 实践教程 - ScreenCoder | 多agents前端代码生成
前端·javascript·人工智能
一个public的class20 小时前
你在浏览器输入一个网址,到底发生了什么?
java·开发语言·javascript
青茶36020 小时前
php怎么实现订单接口状态轮询请求
前端·javascript·php
火车叼位20 小时前
脚本伪装:让 Python 与 Node.js 像原生 Shell 命令一样运行
运维·javascript·python
VT.馒头20 小时前
【力扣】2727. 判断对象是否为空
javascript·数据结构·算法·leetcode·职场和发展
发现一只大呆瓜20 小时前
虚拟列表:从定高到动态高度的 Vue 3 & React 满分实现
前端·vue.js·react.js
鱼毓屿御21 小时前
如何给用户添加权限
前端·javascript·vue.js
JustHappy21 小时前
「web extensions🛠️」有关浏览器扩展,开发前你需要知道一些......
前端·javascript·开源
xixixin_21 小时前
【JavaScript 】从 || 到??:JavaScript 空值处理的最佳实践升级
开发语言·javascript·ecmascript