{"id":18176842,"url":"https://github.com/sahilrajput03/usewhat","last_synced_at":"2025-04-07T10:50:38.435Z","repository":{"id":57388806,"uuid":"314020921","full_name":"sahilrajput03/useWhat","owner":"sahilrajput03","description":null,"archived":false,"fork":false,"pushed_at":"2021-02-25T17:58:47.000Z","size":140,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-02T07:37:34.332Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/sahilrajput03.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-11-18T18:22:11.000Z","updated_at":"2021-07-13T19:39:02.000Z","dependencies_parsed_at":"2022-09-19T02:31:22.652Z","dependency_job_id":null,"html_url":"https://github.com/sahilrajput03/useWhat","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sahilrajput03%2FuseWhat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sahilrajput03%2FuseWhat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sahilrajput03%2FuseWhat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sahilrajput03%2FuseWhat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sahilrajput03","download_url":"https://codeload.github.com/sahilrajput03/useWhat/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247640557,"owners_count":20971555,"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":[],"created_at":"2024-11-02T17:11:42.374Z","updated_at":"2025-04-07T10:50:38.417Z","avatar_url":"https://github.com/sahilrajput03.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `useWhat` - global state management solution\n\n**Before diving into anything in this package read this valuable question @ [stackoverflow](https://stackoverflow.com/questions/40819992/react-parent-component-re-renders-all-children-even-those-that-havent-changed), and you'll understand mostly how useWhat works underneath(though its very simple already!)**.\n\nMOST ASKED QUESTION 😴 :\n\n**Q. What to use for state management in react ?**\n\n\u003e Use `useWhat`, thats all.\n\n**Believe me, nothing can be better than `useWhat` 😎**\n\n## Installation\n\n```bash\nyarn add usewhat\n# or\nnpm i usewhat\n```\n\n## Examples\n\n- New feature added: useWhatPersistent.\n\nWith `useWhatPersistent` api, you can have `state` to be stored in `localStorage` as well in app memory and state will get updated in `localStorage` as soon as `state` is updated. So when you close the tab or refresh the tab, state will persists in the app as it was in the app. (Support for `async-storage` in react native will follow up in upcoming version.)\n\n```js\nimport {useWhatPersistent} from 'usewhat';\n//...\nconst App = () =\u003e {\n  const [db, setDb] = useWhatPersistent('db', 'one');\n  //..\n};\n```\n\n### Example 1\n\n[**Click here to see this example in codesandbox 🔥**](https://codesandbox.io/s/usewhat-example-for-npmjscom-1fopu?file=/src/App.js)\ns\nTip: In below example, I have used `initialState` i.e.,\n\n```js\nconst [home, setHome] = useWhat('home', initialHomeState);\n```\n\n, but you may simply use `useWhat` api like\n\n```js\nconst [home, setHome] = useWhat('home');\n```\n\nand that'll set the initial state as `undefined` (this is same ☂️ as using `const [home, setHome] = useState()` in general react).\n\n```js\nimport React, {useEffect} from 'react';\nimport './styles.css';\nimport {useWhat, getWhat} from 'usewhat';\n\nlet log = console.log;\n\nconst initialHomeState = {rooms: 10};\nconst initialKitchenState = {cups: 200};\n\nconst Pretty = ({data}) =\u003e \u003cpre\u003e{JSON.stringify(data)}\u003c/pre\u003e;\n\nexport default function App() {\n  const [home, setHome] = useWhat('home', initialHomeState);\n  // Initializing `home` namespace with initial data as second parameter.\n  const [kitchen, setKitchen] = useWhat('kitchen', initialKitchenState);\n  // Initializing `kitchen` namespace with initial data as second parameter.\n\n  return (\n    \u003cdiv className=\"App\"\u003e\n      \u003ch2\u003eApp component\u003c/h2\u003e\n      \u003cPretty data={home} /\u003e\n      \u003cPretty data={kitchen} /\u003e\n      \u003cPARENT_COMPONENT /\u003e\n    \u003c/div\u003e\n  );\n}\n\nconst PARENT_COMPONENT = () =\u003e {\n  // Accessing earlier initialized namespaces i.e., `home` and `kitchen` in `App` component.\n  const [home, setHome] = getWhat('home');\n  const [kitchen, setKitchen] = getWhat('kitchen');\n\n  const incrementHome = () =\u003e setHome({rooms: home.rooms + 1});\n\n  const incrementKitchen = () =\u003e setKitchen({cups: kitchen.cups + 1});\n\n  const incrementHomeBy2 = () =\u003e\n    setHome((state) =\u003e ({\n      rooms: state.rooms + 2,\n    }));\n\n  const incrementKitchenBy2 = () =\u003e\n    setKitchen((state) =\u003e ({cups: state.cups + 2}));\n\n  return (\n    \u003cdiv\u003e\n      \u003chr /\u003e\n      \u003ch3\u003eParent Component\u003c/h3\u003e\n      \u003cPretty data={home} /\u003e\n      \u003cPretty data={kitchen} /\u003e\n      \u003cbutton onClick={incrementHome}\u003eIncrement stateHome\u003c/button\u003e\n      \u003cbutton onClick={incrementKitchen}\u003eIncrement stateKitchen\u003c/button\u003e\n      \u003cbr /\u003e\n      \u003cbutton onClick={incrementHomeBy2}\u003eIncrement stateHome by 2\u003c/button\u003e\n      \u003cbutton onClick={incrementKitchenBy2}\u003eIncrement stateKitchen by 2\u003c/button\u003e\n      \u003chr /\u003e\n      \u003cCHILD_COMPONENT /\u003e\n    \u003c/div\u003e\n  );\n};\n\nconst CHILD_COMPONENT = () =\u003e {\n  // Accessing earlier initialized namespaces i.e., `home` and `kitchen` in `App` component.\n  const [home, _] = getWhat('home');\n  const [kitchen, __] = getWhat('kitchen');\n\n  return (\n    \u003cdiv\u003e\n      \u003ch4\u003eChild Component\u003c/h4\u003e\n      \u003cPretty data={home} /\u003e\n      \u003cPretty data={kitchen} /\u003e\n      \u003cbutton onClick={incrementHome}\u003eIncrement stateHome\u003c/button\u003e\n      \u003cbutton onClick={incrementKitchen}\u003eIncrement stateKitchen\u003c/button\u003e\n      \u003cbr /\u003e\n      \u003cbutton onClick={incrementHomeBy2}\u003eIncrement stateHome by 2\u003c/button\u003e\n      \u003cbutton onClick={incrementKitchenBy2}\u003eIncrement stateKitchen by 2\u003c/button\u003e\n    \u003c/div\u003e\n  );\n};\n\nconst incrementHome = () =\u003e {\n  const [home, setHome] = getWhat('home');\n  setHome({rooms: home.rooms + 1});\n};\n\nconst incrementKitchen = () =\u003e {\n  const [kitchen, setKitchen] = getWhat('kitchen');\n  setKitchen({cups: kitchen.cups + 1});\n};\n\nconst incrementHomeBy2 = () =\u003e {\n  const [_, setHome] = getWhat('home');\n  setHome((state) =\u003e ({\n    rooms: state.rooms + 2,\n  }));\n};\n\nconst incrementKitchenBy2 = () =\u003e {\n  const [_, setKitchen] = getWhat('kitchen');\n  setKitchen((state) =\u003e ({cups: state.cups + 2}));\n};\n```\n\n### Example 2\n\n[**Click here to see this example in codesandbox 🔥**](https://codesandbox.io/s/usewhat-example2-fetching-npmjscom-nkm6c?file=/src/App.js)\n\n```js\nimport React, {useEffect} from 'react';\nimport './styles.css';\nimport axios from 'axios';\nimport {useWhat, getWhat} from 'usewhat';\n\nlet log = console.log;\n\nexport default function App() {\n  const [github, setGithub] = useWhat('gh');\n  // Initial state of `gh` namespace is set as `undefined` in this case.\n  useEffect(() =\u003e {\n    axios\n      .get('https://api.github.com')\n      .then((res) =\u003e setGithub(res.data))\n      .catch((e) =\u003e log('#got error#', e));\n  }, [setGithub]);\n\n  return (\n    \u003cdiv className=\"App\"\u003e\n      \u003cChildComponent /\u003e\n    \u003c/div\u003e\n  );\n}\n\nconst ChildComponent = () =\u003e {\n  const [github, setGithub] = getWhat('gh');\n\n  return (\n    \u003cdiv\u003e\n      \u003ch2\u003eChild Component\u003c/h2\u003e\n      \u003cpre\u003e{JSON.stringify(github, null, 2)}\u003c/pre\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n### Example 3 - What not to do with useWhat? This is exactly what it is.\n\n[**(Beware this is about what not to do with `useWhat`) Click here to see this example in codesandbox 🔥**](https://codesandbox.io/s/usewhat-bad-usagenpm-page-exapmle3-f7khu?file=/src/App.js)\n\n```js\nimport React from 'react';\nimport './styles.css';\nimport {useWhat, getWhat} from 'usewhat';\n\nexport default function App() {\n  const [name, setName] = getWhat('person_name'); //initial state = undefined.\n  // *LEARN: Bad usage of `usewhat`, you must only intialise state\n  //  using `useWhat` api and use `getWhat` api in nested components in\n  // such component tree.\n  return (\n    \u003cdiv className=\"App\"\u003e\n      state: {name ?? 'undefined'}\n      \u003cbr /\u003e\n      \u003cbutton\n        onClick={() =\u003e {\n          setName('tom');\n        }}\n      \u003e\n        Set name as \"tom\"\n      \u003c/button\u003e\n      \u003cbr /\u003e\n      \u003cChildComponent /\u003e\n    \u003c/div\u003e\n  );\n}\n\nconst ChildComponent = () =\u003e {\n  const [name, setName] = useWhat('person_name', 'jerry');\n  return (\n    \u003cbutton\n      onClick={() =\u003e {\n        setName('jerry');\n      }}\n    \u003e\n      Set name as 'jerry'\n    \u003c/button\u003e\n  );\n};\n```\n\n### Example 4 (Correcting example 3)\n\n[**(This is correct version of Example 3) Click here to see this example in codesandbox 🔥**](https://codesandbox.io/s/usewhat-bad-usage-fixed-npm-page-exapmle4-x26de?file=/src/App.js:0-921)\n\n```js\nimport React, {useEffect, useRef} from 'react';\nimport './styles.css';\nimport {useWhat, getWhat, log} from 'usewhat';\n\nexport default function App() {\n  const [name, setName] = useWhat('person_name'); //initial state = undefined.\n  // *LEARN: Correct way of using useWhat.\n  return (\n    \u003cdiv className=\"App\"\u003e\n      state: {name ?? 'undefined'}\n      \u003cbr /\u003e\n      \u003cbutton\n        onClick={() =\u003e {\n          setName('tom');\n        }}\n      \u003e\n        Set name as \"tom\"\n      \u003c/button\u003e\n      \u003cbr /\u003e\n      \u003cChildComponent /\u003e\n    \u003c/div\u003e\n  );\n}\n\nconst ChildComponent = () =\u003e {\n  const [name, setName] = getWhat('person_name');\n\n  useEffect(() =\u003e {\n    setName('jerry');\n    // *LEARN: Correct way initializing state in a child component.\n  }, [setName]);\n\n  return (\n    \u003cbutton\n      onClick={() =\u003e {\n        setName('jerry');\n      }}\n    \u003e\n      Set name as 'jerry'\n    \u003c/button\u003e\n  );\n};\n```\n\n### Example 5 Bad usage of useWhat\n\n[**Click here to see this example in codesandbox 🔥**](https://codesandbox.io/s/example-4-usewhat-npmjs-package-readme-lpt9y?file=/src/App.js:83-126)\n\n```js\nimport React from 'react';\nimport {useWhat} from 'usewhat';\n// THIS IS AN ANTIPATTERN CASE FOR USEWHAT\n// You should note that count namespace is initialized twice\n// as Child component App compoment and its a antipatter to\n// usage of useWhat.\n\n// SOLUTION(Refer Example 6): You should host `count` namespace in\n// App component using `useWhat('count', 1)` and utilise `count` in\n// nested components using getWhat api.\n\nfunction App() {\n  return (\n    \u003cdiv\u003e\n      \u003cChild /\u003e\n      \u003cChild /\u003e\n    \u003c/div\u003e\n  );\n}\n\nconst Child = () =\u003e {\n  const [count, setCount] = useWhat('count', 1);\n\n  return (\n    \u003cbutton\n      onClick={() =\u003e {\n        setCount(count + 1);\n      }}\n    \u003e\n      {count}\n    \u003c/button\u003e\n  );\n};\n\nexport default App;\n```\n\n### Example 6 (Fix for e.g. 5)\n\n[**Click here to see this example in codesandbox 🔥**](https://codesandbox.io/s/fix-for-eg-5-usewhat-npm-packagereadme-wfj0p?file=/src/App.js)\n\n```js\nimport './styles.css';\nimport {useWhat, getWhat} from 'usewhat';\n\nconst Child = () =\u003e {\n  const [count, setCount] = getWhat('count');\n\n  return (\n    \u003cbutton\n      onClick={() =\u003e {\n        setCount(count + 1);\n      }}\n    \u003e\n      {count}\n    \u003c/button\u003e\n  );\n};\n\nexport default function App() {\n  useWhat('count', 1); // hoisting the state!\n  return (\n    \u003c\u003e\n      \u003cChild /\u003e\n      \u003cChild /\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n### Example 7 Deeply nesting components\n\n[**Click here to see this example in codesandbox 🔥**](https://codesandbox.io/s/deep-nested-comp-case-usewhat-npm-package-exampleto-be-added-to-readme-puiwo)\n\n```js\n// Code is large to display here, refer above codesnadbox link please!!\n```\n\n### Example 8 If you need performace optimization, you can use [memo](https://reactjs.org/docs/react-api.html#reactmemo).\n\n- Also, I would suggest if you should optimise your components at all or not, by reading [@stackoverflow question](https://stackoverflow.com/questions/53074551/when-should-you-not-use-react-memo) and '#reactmemo-and-friends: When to useMemo and useCallback' article from [kentcdodds](https://kentcdodds.com/blog/usememo-and-usecallback#reactmemo-and-friends).\n\n[**Click here to see this example in codesandbox 🔥**](https://codesandbox.io/s/optimization-and-usewhatnpm-package-eg-7-81yxv?file=/src/App.js)\n\n```js\n// You can safely remove all the log statements, they are just for learning phase only.\nimport {useEffect, memo} from 'react';\nimport './styles.css';\nimport {useWhat, getWhat} from 'usewhat';\n// You can use wrap any component(FOR OPTIMIZATION) to use last rendered result if its props\n// has not changed, yikes!!\n// Read at react docs: https://reactjs.org/docs/react-api.html#reactmemo\nlet log = console.log;\n\nexport default function App() {\n  const [count, setCount] = useWhat('count', 1);\n  const [label, setLabel] = useWhat('label', 'Optimized component...');\n\n  return (\n    \u003cdiv className=\"App\"\u003e\n      \u003ch1\u003eHello CodeSandbox\u003c/h1\u003e\n      \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003e incr\u003c/button\u003e\n      \u003cbutton onClick={() =\u003e setLabel(Math.random)}\u003e change label\u003c/button\u003e\n      \u003cChild1 /\u003e\n      {/* \u003cChild2 /\u003e */} {/* ← ← ← ← ← ← non-optimized way  */}\n      \u003cChild2_Optimized label={label} /\u003e\n    \u003c/div\u003e\n  );\n}\n\nconst Child1 = () =\u003e {\n  const [count, setCount] = getWhat('count');\n  useEffect(() =\u003e {\n    log('Child 1 updated(re-rendered!)');\n  });\n  return \u003cdiv\u003e Child1 - Count: {count} \u003c/div\u003e;\n};\n\nconst Child2_Optimized = memo(Child2);\n\nfunction Child2({label}) {\n  const [count, setCount] = getWhat('count');\n  useEffect(() =\u003e {\n    log('Child 2 updated(re-rendered!)');\n  });\n  return (\n    \u003cdiv\u003e\n      Child2 - Count: {count} {label ?? label}\n      \u003cChild3_Optimized /\u003e\n    \u003c/div\u003e\n  );\n}\n\nconst Child3_Optimized = memo(Child3);\n\nfunction Child3() {\n  const [count, setCount] = getWhat('count');\n  useEffect(() =\u003e {\n    log('Child 3 updated(re-rendered!)');\n  });\n  return \u003cdiv\u003e Child3 - Count: {count} \u003c/div\u003e;\n}\n```\n\n## Why use `useWhat` ?\n\n- Only two apis: useWhat and getWhat.\n- No need to pass props down ever\n- `getWhat` can be called in handler functions as well unlike useState requires you top-level declaration (eslint shit)\n- `getWhat` can be called outside react components, thus fuction callbacks get more neat( as they don't need state to be passed as params, coz they can have their own getWhat inside them )\n- No clutter for maintaing big component trees.\n- Also works for react-native\n\n**Show your support by star the [repo](https://github.com/sahilrajput03/usewhat)**.\n\nThanks, for being here.\n\n~Sahil Rajput\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsahilrajput03%2Fusewhat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsahilrajput03%2Fusewhat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsahilrajput03%2Fusewhat/lists"}