React 简易版本的store管理(演示例子:计数器)

bash 复制代码
npx create-react-app my-redux-app --template typescript
cd my-redux-app
npm install @reduxjs/toolkit react-redux

npm install ajv@^8.0.0
npm install antd
  • package.json
bash 复制代码
{
  "name": "my-redux-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@reduxjs/toolkit": "^2.3.0",
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.18.120",
    "@types/react": "^18.3.12",
    "@types/react-dom": "^18.3.1",
    "ajv": "^8.17.1",
    "antd": "^5.22.2",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-redux": "^9.1.2",
    "react-scripts": "5.0.1",
    "typescript": "^4.9.5",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

项目结构:

  • src/store/counter.ts
javascript 复制代码
import { createSlice, PayloadAction } from '@reduxjs/toolkit'

// 这是一个简单的redux使用示例,可以参考

export interface CounterState {
    value: number;
    status: 'idle' | 'loading' | 'failed';
    list: Array<string>;
}

const initialState: CounterState = {
    value: 0,
    status: 'idle',
    list: [],
};

export const counterSlice = createSlice({
    name: 'counter',
    initialState,
    reducers: {
        increment: (state: CounterState) => {
            // Redux Toolkit allows us to write "mutating" logic in reducers. It
            // doesn't actually mutate the state because it uses the Immer library,
            // which detects changes to a "draft state" and produces a brand new
            // immutable state based off those changes
            state.value += 1;
            state.list.push(`${state.value}`);
        },
        decrement: (state: CounterState) => {
            state.value -= 1;

            state.list.pop();
        },
        incrementByAmount: (state: CounterState, action: PayloadAction<number>) => {
            state.value += action.payload

            state.list.push(`${state.value}`);
        },
    },
})

// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions

export default counterSlice.reducer
  • src/store/store.ts
javascript 复制代码
import { configureStore } from '@reduxjs/toolkit';
import counterSlice from "./counter";
export const store = configureStore({
    reducer: {
        counter: counterSlice,
    },
    middleware: (getDefaultMiddleware) =>
        getDefaultMiddleware({
            serializableCheck: false,
        }),
});

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>;

// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;

// 监听store的变化
store.subscribe(() => {
    // const state = store.getState() as RootState;
    // console.log(state);
});
  • App.tsx
javascript 复制代码
// src/App.tsx
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { RootState } from './store/store';
import { increment, decrement, incrementByAmount } from './store/counter';
import {Button} from 'antd';
const App: React.FC = () => {
  const count = useSelector((state: RootState) => state.counter.value);
  const dispatch = useDispatch();

  return (
      <div style={{ textAlign: 'center', marginTop: '20px' }}>
        <h1>计数器: {count}</h1>
            <Button onClick={() => dispatch(increment())}>增加</Button>&nbsp;&nbsp;
            <Button onClick={() => dispatch(decrement())}>减少</Button>&nbsp;&nbsp;
            <Button onClick={() => dispatch(incrementByAmount(5))}>增加5</Button>
      </div>
  );
};

export default App;
  • index.tsx
javascript 复制代码
// src/index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './store/store';
import App from './App';

const root = ReactDOM.createRoot(
    document.getElementById('root') as HTMLElement
);
root.render(
    <React.StrictMode>
        <Provider store={store}>
            <App />
        </Provider>
    </React.StrictMode>
);
相关推荐
小雨下雨的雨2 小时前
通过鸿蒙PC Electron框架技术完成-井字棋游戏 - 实现详解
前端·javascript·游戏·华为·electron·鸿蒙
meilindehuzi_a2 小时前
掌握 ES6 核心语法与大模型(NLP)项目工程化搭建指南
前端·自然语言处理·es6
IT_陈寒2 小时前
Vue组件通信这个坑我跳了两次才知道怎么爬出来
前端·人工智能·后端
冰暮流星2 小时前
javascript建立对象之构造函数
开发语言·javascript·ecmascript
smallswan3 小时前
第十四 算数运算
linux·服务器·前端
AI_零食3 小时前
甄嬛人物日志-朗读升级 - 鸿蒙PC Electron框架完整技术实现指南
前端·学习·华为·electron·鸿蒙·鸿蒙系统
HackTwoHub3 小时前
WEB扫描器Invicti-Professional-V26.50.0(自动化爬虫扫描)更新
前端·人工智能·chrome·爬虫·web安全·网络安全·自动化
copyer_xyf3 小时前
Python 文件基本操作
前端·后端·python
丑过三八线3 小时前
Umi 配置文件 .umirc.ts 详解
linux·运维·ubuntu·react.js
x***r1513 小时前
linux安装 redis-5.0.5.tar.gz 详细步骤(源码编译、配置、启动)
前端