{"id":13610813,"url":"https://github.com/DJanoskova/vuex-but-for-react","last_synced_at":"2025-04-13T01:33:05.607Z","repository":{"id":41278987,"uuid":"393452597","full_name":"DJanoskova/vuex-but-for-react","owner":"DJanoskova","description":"A state management library for React, heavily inspired by vuex","archived":false,"fork":false,"pushed_at":"2022-09-15T17:37:13.000Z","size":606,"stargazers_count":104,"open_issues_count":2,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-01T18:38:30.971Z","etag":null,"topics":["flux","react","state","state-management"],"latest_commit_sha":null,"homepage":"https://vuex-but-for-react.netlify.app/","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/DJanoskova.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":"2021-08-06T17:31:31.000Z","updated_at":"2024-02-22T15:39:33.000Z","dependencies_parsed_at":"2023-01-18T09:16:03.908Z","dependency_job_id":null,"html_url":"https://github.com/DJanoskova/vuex-but-for-react","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DJanoskova%2Fvuex-but-for-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DJanoskova%2Fvuex-but-for-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DJanoskova%2Fvuex-but-for-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DJanoskova%2Fvuex-but-for-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DJanoskova","download_url":"https://codeload.github.com/DJanoskova/vuex-but-for-react/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223558343,"owners_count":17165112,"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":["flux","react","state","state-management"],"created_at":"2024-08-01T19:01:48.221Z","updated_at":"2024-11-07T17:30:38.600Z","avatar_url":"https://github.com/DJanoskova.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Vuex - But for React! ⚛\n\nEnjoy the vuex API in your React applications with `vuex-but-for-react`, which uses only React Context and React use-sync-external-store under the hood.\n\n`vuex-but-for-react` was engineered with developer experience in mind, making it very easy to use. Invoke your getter or action by using a one-line hook and don't worry about unnecessary renders - **without** using `memo`.\n\nYour component will render only when its getter changes - and it doesn't care about the rest of the store!\n\nAre you on board? Read more 👇\n\n## Installation\n\n`npm install vuex-but-for-react --save`\n\n`yarn add vuex-but-for-react`\n\nTS support included ✨\n\n---\n\n🚨 React versions\n\n**`vuex-but-for-react` \u003e= `3.0.0` works with React `18.0.0`+**\n\nTo use with older react versions, please install `vuex-but-for-react 2.0.6`\n\n## Working example\n\n`store.js`\n```javascript\nconst store = {\n  state: {\n    posts: []\n  },\n  mutations: {\n    POSTS_SET(state, data) {\n      state.posts = data\n    }\n  },\n  actions: {\n    async POSTS_FETCH(context) {\n      const response = await fetch('https://jsonplaceholder.typicode.com/posts')\n      const data = await response.json()\n      context.mutations.POSTS_SET(data)\n    }\n  },\n  getters: {\n    posts (state) {\n      return state.posts\n    }\n  }\n}\n```\n\n`index.js`\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { withStore } from 'vuex-but-for-react';\n\nimport App from './App';\nimport store from './store';\n\nconst AppWithStore = withStore(App, store);\n\nReactDOM.render(\n  \u003cAppWithStore /\u003e,\n  document.getElementById('root')\n);\n```\n\n`Posts.js`\n```javascript\nimport React, { useEffect } from 'react';\nimport { useAction, useGetter } from 'vuex-but-for-react';\n\nconst Posts = () =\u003e {\n  const handleAction = useAction('POSTS_FETCH');\n  const posts = useGetter('posts');\n\n  useEffect(() =\u003e {\n    handleAction();\n  }, [handleAction]) // don't worry, it doesn't re-create!\n  \n  return (\n    \u003cul\u003e\n      {posts.map(post =\u003e \u003cli key={post.id}\u003e{post.title}\u003c/li\u003e)}\n    \u003c/ul\u003e\n  );\n}\n\nexport default Posts\n```\n\nCheck the \u003ca href=\"https://github.com/DJanoskova/vuex-but-for-react/tree/master/examples\"\u003eexamples\u003c/a\u003e section to see JavaScript and TypeScript working apps!\n\n## API\n\n### useAction(`actionName`)\n\nAn action is used for async data logic, especially API calls. You can dispatch mutations and other actions from within an action.\n\nThe function returned by the `useAction()` hook is *never* re-created.\n\n```javascript\nimport { useAction } from 'vuex-but-for-react';\n\nconst PostsPage = () =\u003e {\n  const handleFetch = useAction('POSTS_FETCH');\n\n  useEffect(() =\u003e {\n    handleFetch();\n  }, [handleFetch])\n\n  return (\n    ...\n  )\n}\n```\n\n### useMutation(`actionName`)\n\nA mutation is used for sync data operations. It has access to the current state in order to alter it.\n\nThe function returned by the `useMutation()` hook is *never* re-created.\n\n```javascript\nimport { useMutation } from 'vuex-but-for-react';\n\nconst Counter = () =\u003e {\n  const handleIncrement = useMutation('COUNTER_INCREMENT');\n  const handleDecrement = useMutation('COUNTER_DECREMENT');\n\n  return (\n    \u003c\u003e\n      \u003cbutton onClick={handleDecrement}\u003e-\u003c/button\u003e\n      \u003cbutton onClick={handleIncrement}\u003e+\u003c/button\u003e\n    \u003c/\u003e\n  )\n}\n```\n\n### useGetter(`actionName`)\nA getter gives you the current stored value based on your config. It has access to the current state.\n\nThe data returned by the `useGetter()` hook is updated *only in case the shallow value changes*.\nAn update of one getter value won't trigger the update of another getter value.\n\n```javascript\nimport { useGetter } from 'vuex-but-for-react';\n\nconst PostsPage = () =\u003e {\n  const posts = useGetter('posts');\n\n  return (\n    \u003cul\u003e\n      {posts.map(post =\u003e (\n        \u003cli key={post.id}\u003e{post.title}\u003c/li\u003e\n      ))}\n    \u003c/ul\u003e\n  )\n}\n```\n\n### withStore(`Component`, `config`)\n\nIn order to initialize the global store, wrap your (chosen) root component in your store config.\n\n```javascript\nimport { withStore } from 'vuex-but-for-react';\n\nconst AppWithStore = withStore(App, store);\n```\n\nAnd more amazing stuff!\n\n#### useActionOnMount(`actionName`)\n\nAvoid calling useEffect manually. Just pass the action name and it will be executed on component mount automatically.\n\n```javascript\nimport { useActionOnMount, useGetter } from 'vuex-but-for-react';\n\nconst PostsPage = () =\u003e {\n  useActionOnMount('POSTS_FETCH');\n  const posts = useGetter('posts');\n\n  return (\n    ...\n  )\n}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDJanoskova%2Fvuex-but-for-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDJanoskova%2Fvuex-but-for-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDJanoskova%2Fvuex-but-for-react/lists"}