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();
}); 
相关推荐
To_OC2 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
To_OC3 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
小林ixn4 小时前
从 ??= 到 onKeyDown:一个 React 组件的“自我修养”
前端·javascript·react.js
এ慕ོ冬℘゜4 小时前
前端实战:jQuery 多条件联合搜索(标题模糊查询 + 日历时间段筛选)
前端·javascript·jquery
随心点儿5 小时前
js postMessage 实现跨域发送消息-应用示例
javascript·ecmascript·postmessage
kyriewen6 小时前
我让AI改一个bug——它偷偷动了5个我没让它碰的地方
前端·javascript·ai编程
gis开发之家11 小时前
《Vue3 从入门到大神35篇》Vue3 源码详解(五):effect 依赖收集原理——track 与 trigger 是如何工作的?
javascript·typescript·前端框架·vue3·vue3源码
半个落月11 小时前
用 React 搭一个 WebGPU 模型加载页:从状态驱动到可复用进度条
前端·react.js
橘子星12 小时前
我一个前端切图仔,凭什么能在浏览器里跑大模型?
前端·javascript·前端框架
半个落月12 小时前
用 LangChain JS 做可控写作实验:理解温度参数、提示词与异步调用
javascript·人工智能·后端