{"id":25020891,"url":"https://github.com/frontainer/fluent-reducer","last_synced_at":"2025-03-30T10:26:25.968Z","repository":{"id":39098306,"uuid":"268224548","full_name":"frontainer/fluent-reducer","owner":"frontainer","description":"TypeSafe \u0026 Immutable useReducer","archived":false,"fork":false,"pushed_at":"2023-01-06T07:34:46.000Z","size":3367,"stargazers_count":0,"open_issues_count":25,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-20T00:41:23.845Z","etag":null,"topics":["immutable","react","reducer","typescript"],"latest_commit_sha":null,"homepage":"https://sable-virt.github.io/fluent-reducer/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/frontainer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-31T06:43:26.000Z","updated_at":"2020-06-07T06:20:09.000Z","dependencies_parsed_at":"2023-02-05T15:31:38.421Z","dependency_job_id":null,"html_url":"https://github.com/frontainer/fluent-reducer","commit_stats":null,"previous_names":["frontainer/fluent-reducer","sable-virt/fluent-reducer"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontainer%2Ffluent-reducer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontainer%2Ffluent-reducer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontainer%2Ffluent-reducer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontainer%2Ffluent-reducer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frontainer","download_url":"https://codeload.github.com/frontainer/fluent-reducer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246304467,"owners_count":20755907,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["immutable","react","reducer","typescript"],"created_at":"2025-02-05T12:18:06.439Z","updated_at":"2025-03-30T10:26:25.949Z","avatar_url":"https://github.com/frontainer.png","language":"TypeScript","readme":"# fluent-reducer\nEasy \u0026 TypeSafe \u0026 Immutable reducer(No Redux Dependency)\n\n## How to use\n\n```\nnpm i -S fluent-reducer immer\n```\n\n### [optional] Install your framework\nexample for react\n```\nnpm i -S react\n```\n\n## Example\n\n- [React](https://github.com/sable-virt/fluent-reducer-examples/tree/master/react-example)\n- [Vue](https://github.com/sable-virt/fluent-reducer-examples/tree/master/vue-example)\n- [Angular](https://github.com/sable-virt/fluent-reducer-examples/tree/master/angular-example)\n\n### 1. Define State Object\n```\nexport interface IRootState {\n  name: string\n}\nconst RootState: IRootState = {\n  name: 'unknown'\n}\n```\n\n### 2. Create FluentReducer\n```\n// 'root' is unique ID\nimport { ReactFluentReduer } from 'fluent-reducer/react'\n// for not react app\n// import { FluentReduer } from 'fluent-reducer'\nexport const rootReducer = new ReactFluentReducer\u003c'root', IRootState\u003e(RootState, {\n  verbose: true,\n  middlewares: [(state, action) =\u003e {\n    // this state can edit. not plane object, so if you save state like localstorage, use subscribe\n    console.log(state, action)\n  }]\n})\n```\n\n### 3. Sync Action\n```\nexport const changeName = rootReducer.sync\u003cstring\u003e('CHANGE_NAME', (state, name) =\u003e {\n  state.name = name\n})\n```\n\n### 4. Async Action\n```\nconst asyncChangeState = reducer.async\u003cstring, string, Error\u003e('ASYNC_CHANGE_NAME', (name, dispatch, getState) =\u003e {\n  return new Promise(resolve =\u003e {\n    setTimeout(() =\u003e {\n      resolve(name)\n    }, 3000)\n  })\n}, {\n  // before promise action\n  started(state, params) {\n    console.log('started', params)\n    state.state = 'started'\n  },\n  // promise rejected action\n  failed(state, { error }) {\n    console.error(error)\n  },\n  // promise resolved action\n  done(state, { result }) {\n    state.name = result\n    console.log('done')\n  }\n})\n```\n\n### 5. react hooks\n\n```\nexport const MyExample: React.FC = () =\u003e {\n  const [state, dispatch] = rootReducer.useFluentReducer()\n  const _handleOnClick = useCallback(() =\u003e {\n    // execute changeName action\n    dispatch(changeName(Date.now().toString()))\n  }, [dispatch])\n  return (\n    \u003cdiv onClick={_handleOnClick}\u003e{state.name}\u003c/div\u003e\n  )\n}\n```\n\n### 6. subscribe/unsubscribe\n\n```\nrootReducer.subscribe((state, action) =\u003e {\n  // this state is readonly. if you want to update state, use middlewares option.\n  console.log(state, action)\n})\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrontainer%2Ffluent-reducer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrontainer%2Ffluent-reducer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrontainer%2Ffluent-reducer/lists"}