SuperAPI AI Directory

ssd-react-state

Frontend & websites

View repository

Updated 10-15 21:41

About this skill

SSD React State — Redux Usage Standard

Context

SSD uses Redux Toolkit for global state management in React. Every module with global state must create its own slice and add it to the rootReducer at src/redux/rootReducer.ts

How Redux Works

Redux works through 3 main parts:

  1. Store — the store that holds all state data
  2. Action — an instruction with a payload sent to the reducer to change state
  3. Reducer — the process of changing state according to an action

Components work with Redux using:

  • Subscribe (useAppSelector) — receives state values from the store
  • Dispatch (useAppDispatch) — sends actions to the reducer

Main Rules

  1. Must create a slice in src/app/modules/[ModuleName]/[moduleName]Slice.ts
  2. Must export the type of State and Payload every time
  3. Must export actions, reducer, and may export selector
  4. Must add the reducer to the rootReducer in src/redux/rootReducer.ts
  5. Must use useAppSelector and useAppDispatch from src/redux/hook.ts only

Step 1: Create a Slice

Create a file at src/app/modules/[ModuleName]/[moduleName]Slice.ts

// src/app/modules/counter/counterSlice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";

// 1. สร้าง Type ของ State (ต้องทำ)
export type CounterState = {
    count: number;
    settings: {
        showCount: boolean;
    };
};

// 2. กำหนดค่าเริ่มต้น (ต้องทำ)
const initialState: CounterState = {
    count: 0,
    settings: {
        showCount: true,
    },
};

// 3. สร้าง Type ของ Payload สำหรับ action ที่มีหลายตัวแปร (ควรทำ)
// ตั้งชื่อตาม Action และลงท้ายด้วย Payload
export type SetShowCountPayload = {
    count: number;
    showCount: boolean;
};

// 4. สร้าง Slice (ต้องทำ)
const counterSlice = createSlice({
    name: "counter", // ชื่อ slice ควรเป็นชื่อ Module
    initialState,
    reducers: {
        setCount: (state, action: PayloadAction<number>) => {
            state.count = action.payload;
        },
        setShowCount: (state, action: PayloadAction<SetShowCountPayload>) => {
            state.count = action.payload.count;
            state.settings.showCount = action.payload.showCount;
        },
    },
});

// 5. Export actions (ต้องทำ)
export const { setCount, setShowCount } = counterSlice.actions;

// 6. Export selector (ไม่จำเป็น แต่แนะนำ)
export const countSelector = (state: RootState) => state.counter;

// 7. Export reducer (ต้องทำ)
export default counterSlice.reducer;

If there are multiple slices in the same module

Name it in the style [moduleName][SubModule]Slice.ts such as orderDetailSlice.ts, orderListSlice.ts

Step 2: Add to rootReducer

Edit the file src/redux/rootReducer.ts:

import { counterSlice } from "../app/modules/counter/counterSlice";
import { combineReducers } from "@reduxjs/toolkit";

export const rootReducer = combineReducers({
    layout: persistReducer(persistConfig, layoutSlice),
    counter: counterSlice, // เพิ่ม slice ใหม่ที่นี่
});

Step 3: Use in a Component

import { useAppSelector, useAppDispatch } from "../../redux/hook";
import { setCount, setShowCount, countSelector } from "./counterSlice";

export const CounterComponent = () => {
    // Subscribe ค่าจาก Redux
    const { count, settings } = useAppSelector(countSelector);
    // หรือ: const { count } = useAppSelector(state => state.counter);

    // เรียกใช้ dispatch
    const dispatch = useAppDispatch();

    const handleIncrement = () => {
        // dispatch action ที่มี payload เดียว
        dispatch(setCount(count + 1));
    };

    const handleToggleShow = () => {
        // dispatch action ที่ payload เป็น object
        dispatch(setShowCount({
            count: count,
            showCount: !settings.showCount,
        }));
    };

    return (
        <div>
            <h1>Count: {count}</h1>
            <button onClick={handleIncrement}>เพิ่ม</button>
            <button onClick={handleToggleShow}>
                {settings.showCount ? "ซ่อน" : "แสดง"}
            </button>
        </div>
    );
};

Redux File Structure

src/
├── redux/
│   ├── rootReducer.ts  # รวม reducer ทั้งหมด
│   └── hook.ts         # useAppSelector, useAppDispatch
└── app/modules/
    └── [ModuleName]/
        └── [moduleName]Slice.ts  # slice ของแต่ละ module