{"id":16179322,"url":"https://github.com/1111mp/simple-store","last_synced_at":"2026-05-02T03:31:26.597Z","repository":{"id":191101616,"uuid":"683277268","full_name":"1111mp/simple-store","owner":"1111mp","description":"Manage your state in the easiest way for React.","archived":false,"fork":false,"pushed_at":"2023-08-30T04:45:17.000Z","size":127,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-18T03:05:04.940Z","etag":null,"topics":["react","react-hooks","reactjs","simple-store","state-management"],"latest_commit_sha":null,"homepage":"https://github.com/1111mp/simple-store","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/1111mp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-26T04:02:41.000Z","updated_at":"2023-11-25T16:33:57.000Z","dependencies_parsed_at":"2024-10-30T05:21:21.949Z","dependency_job_id":null,"html_url":"https://github.com/1111mp/simple-store","commit_stats":{"total_commits":10,"total_committers":2,"mean_commits":5.0,"dds":0.09999999999999998,"last_synced_commit":"3e9e86cd0a513af7f01bf25dc2d5c58ccf0b743f"},"previous_names":["1111mp/simple-store"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/1111mp/simple-store","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1111mp%2Fsimple-store","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1111mp%2Fsimple-store/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1111mp%2Fsimple-store/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1111mp%2Fsimple-store/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/1111mp","download_url":"https://codeload.github.com/1111mp/simple-store/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1111mp%2Fsimple-store/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32522235,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T01:12:54.858Z","status":"online","status_checked_at":"2026-05-02T02:00:05.923Z","response_time":132,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react","react-hooks","reactjs","simple-store","state-management"],"created_at":"2024-10-10T05:27:09.874Z","updated_at":"2026-05-02T03:31:26.572Z","avatar_url":"https://github.com/1111mp.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## simple-store\n\nManage your state in the easiest way for React.\n\n## Installation\n\n```shell\nnpm run install @the1111mp/simple-store\n# Or\nyarn add @the1111mp/simple-store\n```\n\n## Example\n\nYou can see the code: [simple-store-example](https://github.com/1111mp/simple-store/tree/main/example)\n\nOr\n\n[![Edit](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/simple-store-example-cfj25d)\n\n## Quick Start\n\n#### Basic usage\n\nCreate a `userStore` through the `createStore` method:\n\n```typescript\n// user.store.ts\nimport { createStore } from \"@the1111mp/simple-store\";\n\ntype UseStore = { name: string; age: number };\n\n// directly assign the initialized value\nexport const [userStore, resetStore] = createStore\u003cUseStore\u003e({\n  name: \"Tom\",\n  age: 18,\n});\n\n// Or\n\n// Use a function to get the initialized value （sync）\nexport const [userStore, resetStore] = createStore\u003cUseStore\u003e(() =\u003e {\n  // you can do something\n\n  return {\n    name: \"Tom\",\n    age: 18,\n  };\n});\n\n// Or\n\n// Use a function to get the initialized value (async)\n// Remember this will triggers an update\nexport const [userStore, resetStore] = createStore\u003cUseStore\u003e(\n  { name: \"\", age: 0 },\n  async () =\u003e {\n    // you can do something\n    const { name, age } = await fetch(\"/user\");\n\n    return {\n      name,\n      age,\n    };\n  }\n);\n\n// App.tsx\nimport { userStore } from \"user.store\";\n\nexport const App: React.FC = () =\u003e {\n  const [{ name, age }, updateUserStore] = userStore();\n\n  return (\n    \u003cdiv\u003e\n      App:\n      \u003cbr /\u003e\n      name: \u003cspan\u003e{name}\u003c/span\u003e\n      \u003cbr /\u003e\n      age: \u003cspan\u003e{age}\u003c/span\u003e\n      \u003cbr /\u003e\n      \u003cbutton\n        onClick={() =\u003e {\n          updateUserStore((store) =\u003e {\n            return { name: \"Jim\", age: 16 };\n          });\n        }}\n      \u003e\n        update\n      \u003c/button\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n#### Custom hooks\n\n```typescript\n// user.store.ts\nimport { createStore } from \"@the1111mp/simple-store\";\n\ntype UseStore = { name: string; age: number };\n\nconst [userStore] = createStore\u003cUseStore\u003e({\n  name: \"Tom\",\n  age: 18,\n});\n\nexport function useUserStore() {\n  const [{ name, age }, updateUserStore] = userStore();\n\n  const updateName = (name: string) =\u003e {\n    updateUserStore((store) =\u003e ({ ...store, name }));\n  };\n\n  return {\n    name,\n    age,\n    updateName,\n  };\n}\n\n// App.tsx\nimport { useUserStore } from \"user.store\";\n\nexport const App: React.FC = () =\u003e {\n  const { name, age, updateName } = useUserStore();\n\n  return (\n    \u003cdiv\u003e\n      App:\n      \u003cbr /\u003e\n      name: \u003cspan\u003e{name}\u003c/span\u003e\n      \u003cbr /\u003e\n      age: \u003cspan\u003e{age}\u003c/span\u003e\n      \u003cbr /\u003e\n      \u003cbutton\n        onClick={() =\u003e {\n          updateName(\"Jim\");\n        }}\n      \u003e\n        update\n      \u003c/button\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n\u003e It is recommended to use custom hooks to split and manage your Store.\n\n#### Performance optimization\n\nWith the `depsFn` function, you can control the `state` you want to subscribe to to avoid unwanted updates. This is similar to the `deps` parameter of React's `useMemo` or `useEffect`.\n\n```typescript\nimport { createStore } from \"@the1111mp/simple-store\";\n\ntype UseStore = { name: string; age: number };\n\nconst [userStore] = createStore\u003cUseStore\u003e({\n  name: \"Tom\",\n  age: 18,\n});\n\nexport function useUserNameStore() {\n  // depsFn\n  const [{ name }, updateUserStore] = userStore((store) =\u003e [store.name]);\n\n  const updateName = (name: string) =\u003e {\n    updateUserStore((store) =\u003e ({ ...store, name }));\n  };\n\n  return {\n    name,\n    updateName,\n  };\n}\n```\n\n#### How to use it in class components\n\n\u003e Cannot pass `userStore` directly to `withStore`.\n\n```typescript\n// user.store.ts\nimport { createStore } from \"@the1111mp/simple-store\";\n\ntype UseStore = { name: string; age: number };\n\nconst [userStore] = createStore\u003cUseStore\u003e({\n  name: \"Tom\",\n  age: 18,\n});\n\nexport function useUserStore() {\n  const [{ name, age }, updateUserStore] = userStore();\n\n  const updateName = (name: string) =\u003e {\n    updateUserStore((store) =\u003e ({ ...store, name }));\n  };\n\n  return {\n    name,\n    age,\n    updateName,\n  };\n}\n\n// App.tsx\nimport { Component } from \"react\";\nimport { withStore } from \"@the1111mp/simple-store\";\nimport { useUserStore } from \"user.store\";\n\ntype Props = ReturnType\u003ctypeof useUserStore\u003e \u0026 {};\n\nclass App extends Component\u003cProps\u003e {\n  render(): React.ReactNode {\n    const { name, age, updateName } = this.props;\n\n    return (\n      \u003cdiv\u003e\n        App\n        \u003cbr /\u003e\n        name: {name}\n        \u003cbr /\u003e\n        age: {age}\n        \u003cbr /\u003e\n        \u003cbutton\n          onClick={() =\u003e {\n            updateName(\"Jim\");\n          }}\n        \u003e\n          update\n        \u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n\nexport default withStore(useUserStore, (userStore) =\u003e ({\n  ...userStore,\n}))(App);\n```\n\n#### Dependencies between stores\n\nSingle store:\n\n```typescript\n// weather.store.ts\nimport { createStore } from \"@the1111mp/simple-store\";\n\nexport type WeatherStore = {\n  weather: string;\n  temperature: number;\n};\n\nexport const [weatherStore] = createStore\u003cWeatherStore\u003e({\n  weather: \"sunny\",\n  temperature: 28,\n});\n\nexport function useWeatherNameStore() {\n  const [{ weather }, updateStore] = weatherStore((store) =\u003e [store.weather]);\n\n  const updateWeather = (weather: string) =\u003e {\n    updateStore((store) =\u003e {\n      return {\n        ...store,\n        weather,\n      };\n    });\n  };\n\n  return {\n    weather,\n    updateWeather,\n  };\n}\n\nexport function useTempStore() {\n  const [{ temperature }, updateStore] = weatherStore((store) =\u003e [\n    store.temperature,\n  ]);\n\n  const updateTemperature = (temperature: number) =\u003e {\n    updateStore((store) =\u003e {\n      return {\n        ...store,\n        temperature,\n      };\n    });\n  };\n\n  return {\n    temperature,\n    updateTemperature,\n  };\n}\n\nexport function useWeatherStore() {\n  const { weather, updateWeather } = useWeatherNameStore();\n  const { temperature, updateTemperature } = useTempStore();\n\n  return {\n    weather,\n    temperature,\n    updateWeather,\n    updateTemperature,\n  };\n}\n\n// Test.tsx\nimport { Component } from \"react\";\nimport { withStore } from \"@the1111mp/simple-store\";\nimport { useWeatherStore } from \"./weather.store\";\n\ntype Props = ReturnType\u003ctypeof useWeatherStore\u003e \u0026 {};\n\nclass Test extends Component\u003cProps\u003e {\n  render(): React.ReactNode {\n    console.log(\"rerender from Test\");\n    const { weather, temperature, updateWeather, updateTemperature } =\n      this.props;\n    return (\n      \u003cdiv\u003e\n        Test\n        \u003cbr /\u003e\n        weather: {weather}\n        \u003cbr /\u003e\n        temperature: {temperature} 摄氏度\n        \u003cbr /\u003e\n        \u003cbutton\n          onClick={() =\u003e {\n            updateWeather(\"hot\");\n          }}\n        \u003e\n          update weather\n        \u003c/button\u003e\n        \u003cbr /\u003e\n        \u003cbutton\n          onClick={() =\u003e {\n            updateTemperature(30);\n          }}\n        \u003e\n          update temperature\n        \u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n\nexport default withStore(useWeatherStore, (weatherStore) =\u003e ({\n  ...weatherStore,\n}))(Test);\n```\n\nMultiple Stores:\n\n```typescript\n// user.store.ts\nimport { createStore } from \"@the1111mp/simple-store\";\n\ntype UseStore = { name: string; age: number };\n\nexport const [userStore] = createStore\u003cUseStore\u003e({\n  name: \"Tom\",\n  age: 18,\n});\n\nexport function useUsertore() {\n  // depsFn\n  const [{ name, age }, updateStore] = userStore();\n\n  const updateUserStore = (user: Partial\u003cUseStore\u003e) =\u003e {\n    updateStore((store) =\u003e ({ ...store, ...user }));\n  };\n\n  return {\n    name,\n    age,\n    updateUserStore,\n  };\n}\n\n// weather.store.ts\nimport { createStore } from \"@the1111mp/simple-store\";\nimport { useUserStore } from \"./user.store\";\n\nexport type WeatherStore = {\n  weather: string;\n  temperature: number;\n};\n\nexport const [weatherStore] = createStore\u003cWeatherStore\u003e({\n  weather: \"sunny\",\n  temperature: 28,\n});\n\nexport function useInfoStore() {\n  const { name, age, updateUserStore } = useUserStore();\n  const [{ weather, temperature }, updateWeatherStore] = weatherStore();\n\n  const updateWeatherStore = (weather: Partial\u003cWeatherStore\u003e) =\u003e {\n    updateStore((store) =\u003e {\n      return {\n        ...store,\n        ...weather,\n      };\n    });\n  };\n\n  return {\n    name,\n    age,\n    weather,\n    temperature,\n    updateUserStore\n    updateWeatherStore,\n  };\n}\n```\n\n#### Read only\n\nIn some scenarios, we only want to read the current value of a model, without subscribing to its updates.\n\n`useStore.store`:\n\n```typescript\nimport { createStore } from \"@the1111mp/simple-store\";\n\ntype UseStore = { name: string; age: number };\n\nexport const [userStore] = createStore\u003cUseStore\u003e({\n  name: \"Tom\",\n  age: 18,\n});\n\n// will not subscribe to updates\nexport function useInfoStore() {\n  const { name, age } = userStore.store;\n\n  return {\n    name,\n    age,\n  };\n}\n```\n\n## API\n\n#### createStore\n\n```typescript\ntype Store = Record\u003cstring, unknown\u003e;\ntype ResetStore = (notify?: boolean) =\u003e void;\n\nexport declare function createStore\u003cT extends Store\u003e(\n  initial: T,\n  initialFn?: (store: T) =\u003e Promise\u003cT\u003e\n): [UseStore\u003cT\u003e, ResetStore];\nexport declare function createStore\u003cT extends Store\u003e(\n  initial: () =\u003e T,\n  initialFn?: (store: T) =\u003e Promise\u003cT\u003e\n): [UseStore\u003cT\u003e, ResetStore];\n```\n\nCreate a Store.\n\n#### UseStore\n\n```typescript\ntype UpdateStoreNormal\u003cT\u003e = (store: T) =\u003e T;\ntype UpdateStoreWithPromise\u003cT\u003e = (store: T) =\u003e Promise\u003cT\u003e;\ntype UpdateStore\u003cT\u003e = (\n  val: T | UpdateStoreNormal\u003cT\u003e | UpdateStoreWithPromise\u003cT\u003e\n) =\u003e void;\ntype DepFn\u003cT\u003e = (store: T) =\u003e unknown[];\n\ntype UseStore\u003cT\u003e = {\n  (depsFn?: DepFn\u003cT\u003e): [T, UpdateStore\u003cT\u003e];\n  store?: T;\n};\n```\n\nCall the return value of the createStore function.\n\n#### resetStore\n\nReset your store data.\n\n```typescript\ntype ResetStore = (notify?: boolean) =\u003e void;\n```\n\nThe param of `notify` default is `true`, reset store data then notify to trigger once update.\n\n#### withStore\n\n```typescript\nexport declare function withStore\u003cTStoreProps, TOwnProps, T\u003e(\n  useStore: UseStore\u003cT\u003e,\n  mapModelToProps: MapModelToProps\u003cTStoreProps, TOwnProps, T\u003e\n): InferableComponentEnhancerWithProps\u003cTStoreProps, TOwnProps\u003e;\nexport declare function withStore\u003cTStoreProps, TOwnProps, Model\u003e(\n  useStores: UseStore\u003cany\u003e[],\n  mapModelToProps: MapModelToProps\u003cTStoreProps, TOwnProps, any[]\u003e\n): InferableComponentEnhancerWithProps\u003cTStoreProps, TOwnProps\u003e;\n```\n\nUsed to link `store` and `class components`, similar to `connect` of `react-redux`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F1111mp%2Fsimple-store","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F1111mp%2Fsimple-store","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F1111mp%2Fsimple-store/lists"}