🔷Tải xuống

npm install ron-store

🔷Mô tả

 - Ron Store là một thư viện state management nhẹ cho React + TypeScript, tổ chức state theo “package” với reducers và hook đi kèm, hỗ trợ lưu trữ có chọn lọc vào localStorage và dev log để theo dõi luồng dữ liệu
 - Điểm chính
    - Cấu trúc “package”:
        - Khai báo State và Reducer theo kiểu TypeScript
        - Tạo Package với initState và reducers như increment, decrement cập nhật state qua pkg.setState
    - Store toàn cục:
        - Đăng ký các package trong packages
        - whiteList để chỉ định package được lưu vào localStorage
        - devLog bật log để debug
    - Tích hợp ứng dụng:
        - Bọc app bằng <RonStoreProvider store={store}> trong main.tsx
    - Sử dụng trong component:
        - Lấy package từ store: usePkgSelector
        - Làm việc với package: usePackage để nhận state và dispatch
        - Lắng nghe thay đổi state: usePkgSubcribe
        - Ví dụ bộ đếm tăng/giảm bằng dispatch("increment" | "decrement", { step })

{A679558F-A101-4E01-B2B0-E2892395D8C6}.png

{48F48BF2-9DAC-49F5-8570-F5DFED3B0472}.png

🔷 Sử dụng

🟣Tạo package cho dữ liệu - lib/store/pkg/count.pkg.ts

// Tạo type cho State
export type CountState = {
  count: number;
};
// Tạo type cho Reducer
export type CountReducer = {
  increment: Action<CountState>;
  decrement: Action<CountState>;
};
//Khởi tạo state ban đầu
const initState: CountState = {
  count: 0,
};
//Tạo package để lưu trữ state
const countPkg = new Package<CountState, CountReducer>({
  initState: initState,
  reducers: {
    increment: (pkg, payload) => {
      const { step } = payload;
      pkg.setState((state) => ({
        ...state,
        count: state.count + step,
      }));
    },
    decrement: (pkg, payload) => {
      const { step } = payload;
      pkg.setState((state) => ({
        ...state,
        count: state.count - step,
      }));
    },
  },
});
export default countPkg;

⚫Tạo store cho toàn ứng dụng - lib/store/store.ts

- packages chứa các package
- whiteList chứa các tên package mà cho phép lưu state tại localstorage
- devLog cho phép dev xem log ở console về luồng dữ liệu
import countPkg from "./pkgs/count.pkg";

const store = new Store({
  packages:{
    countPkg: countPkg
  },
  whiteList:["countPkg"],
  devLog: true
})
export default store

🟤Thêm provider vào file gốc - main.tsx

createRoot(document.getElementById("root")!).render(
  <RonStoreProvider store={store}>
    <App />
  </RonStoreProvider>
);

🔵Ví dụ sử dụng

export default function App() {
  // Lấy package từ store với usePkgSelector<State của package cần lấy>
  const countPkg = usePkgSelector<CountState>(
    (state) => state.packages["countPkg"]
  ); 
  // Sử dụng package với usePackage<typeof State, typeof Reducer>
  const {
    state: { count },
    dispatch,
  } = usePackage<CountState, CountReducer>({
    pkg: countPkg,
  });
  // Sử dụng usePkgSubcribe để đăng ký một subcribe, khi state thay đổi thì action thực hiện
  usePkgSubcribe({
    pkg: countPkg,
    action: (state) => {
      console.log("Subcribe test ", state);
    },
  });
  const upDownHandle = (type: "up" | "down") => {
    const step = 1;
    switch (type) {
      case "up": {
        dispatch("increment", { step });
        break;
      }
      case "down": {
        dispatch("decrement", { step });
        break;
      }
    }
  };
  return (
    <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
      <div className="bg-white shadow-lg rounded-2xl p-8 w-80 text-center">
        <h1 className="text-2xl font-semibold text-gray-800 mb-6">
          Count: {count}
        </h1>
        <div className="flex items-center justify-center space-x-6">
          <button
            onClick={() => upDownHandle("down")}
            className="w-12 h-12 flex items-center justify-center rounded-full bg-red-500 text-white text-xl font-bold shadow-md hover:bg-red-600 active:scale-95 transition"
          >
            -
          </button>
          <button
            onClick={() => upDownHandle("up")}
            className="w-12 h-12 flex items-center justify-center rounded-full bg-green-500 text-white text-xl font-bold shadow-md hover:bg-green-600 active:scale-95 transition"
          >
            +
          </button>
        </div>
      </div>
    </div>
  );
}