{"id":13547192,"url":"https://github.com/MananTank/radioactive-state","last_synced_at":"2025-04-02T19:32:47.763Z","repository":{"id":138301896,"uuid":"289946738","full_name":"MananTank/radioactive-state","owner":"MananTank","description":"☢ Make Your React App Truly Reactive!","archived":false,"fork":false,"pushed_at":"2022-08-27T00:54:14.000Z","size":4623,"stargazers_count":309,"open_issues_count":0,"forks_count":49,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-04-21T13:54:36.530Z","etag":null,"topics":["hook","hooks","proxy","react","react-hook","react-hooks","reactive","reactive-bindings","reactive-props","state-management"],"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/MananTank.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,"governance":null}},"created_at":"2020-08-24T14:12:24.000Z","updated_at":"2024-04-14T08:01:43.000Z","dependencies_parsed_at":"2023-05-29T03:30:38.805Z","dependency_job_id":null,"html_url":"https://github.com/MananTank/radioactive-state","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/MananTank%2Fradioactive-state","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MananTank%2Fradioactive-state/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MananTank%2Fradioactive-state/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MananTank%2Fradioactive-state/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MananTank","download_url":"https://codeload.github.com/MananTank/radioactive-state/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246880265,"owners_count":20848836,"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":["hook","hooks","proxy","react","react-hook","react-hooks","reactive","reactive-bindings","reactive-props","state-management"],"created_at":"2024-08-01T12:00:52.295Z","updated_at":"2025-04-02T19:32:42.750Z","avatar_url":"https://github.com/MananTank.png","language":"JavaScript","readme":"\u003c!-- logo --\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg width='300' src=\"img/logo-and-text.svg\"\u003e\n\u003c/p\u003e\n\n\u003c!-- tag line --\u003e\n\u003ch3 align='center'\u003e Make Your React App Truly Reactive ! \u003c/h3\u003e\n\n\u003c!-- primary badges --------------------------------------\u003e\n\u003cp align=\"center\"\u003e\n  \u003c!-- version --\u003e\n  \u003cimg src='https://img.shields.io/github/package-json/v/MananTank/radioactive-state?color=blue\u0026label=npm\u0026style=flat' /\u003e\n  \u003c!-- size --\u003e\n  \u003cimg src='https://img.shields.io/bundlephobia/minzip/radioactive-state?color=success\u0026label=size' /\u003e\n  \u003c!-- downloads npm per week  --\u003e\n  \u003cimg src='https://img.shields.io/npm/dw/radioactive-state?color=blueviolet' /\u003e\n  \u003c!-- chat --\u003e\n  \u003ca href='https://join.slack.com/t/radioactive-state/shared_invite/zt-gwd1rsvr-vkoizw5RG5rk9rwsdgT3gQ'\u003e\n    \u003cimg src='https://img.shields.io/badge/Chat-Slack-red'\u003e\n  \u003c/a\u003e\n  \u003c!-- stars --\u003e\n  \u003cimg src='https://img.shields.io/github/stars/MananTank/radioactive-state?style=social\u0026color=%23FFB31A' /\u003e\n  \u003c!-- follow --\u003e\n  \u003cimg src='https://img.shields.io/github/followers/MananTank?label=Follow\u0026style=social\u0026color=%23FFB31A' /\u003e\n  \u003c!-- Twitter intent --\u003e\n  \u003ca href='https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2FMananTank%2Fradioactive-state\u0026via=MananTank_\u0026text=Make%20your%20@reactjs%20App%20Truly%20Reactive%20with%20radioactive-state\u0026hashtags=react%2CradioactiveState' target='_blank'\u003e\n    \u003cimg src='https://img.shields.io/twitter/url/http/shields.io.svg?style=social'/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003c!-- Coverage badges ---------------------------------- --\u003e\n\u003cp align='center'\u003e\n  \u003cimg src='https://img.shields.io/badge/Stmts-100%25-success' /\u003e\n  \u003cimg src='https://img.shields.io/badge/Branch-100%25-success' /\u003e\n  \u003cimg src='https://img.shields.io/badge/Funcs-100%25-success' /\u003e\n  \u003cimg src='https://img.shields.io/badge/Lines-100%25-success' /\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\n\n\n\n## Features\n\n☢ Deeply Reactive, Directly Mutate State at any level to Update Component\n\n⚡ Blazing Fast - 25% faster than `useState`\n\n📺 No Extra Re-Renders - Auto Mutation batching\n\n🌿 Always Fresh State, _unlike_ `useState`\n\n🧬 Reactive Bindings For Inputs\n\n⚛ Reactive Props\n\n☕ Zero Dependencies, Ultra Light-Weight `\u003c 1kb`\n\n\u003cbr/\u003e\n\n\n\n\n## 🌻 Motivation\n\nWhile the React's `useState` hook has been great for simple states, it is still **a pain to update a complex state**.\n\nIt also comes with other problems like **not having the access to fresh state right away** after the new state is set and closure problems because of state's value only updating after a re-render.\n\nWe can eliminate these problems, Improve performance and Introduce exciting new features in React with a **Truly Reactive State !**\n\nEnter `radioactive-state`\n\n\u003cbr/\u003e\n\n\n## Installation\n```bash\nnpm i radioactive-state\n```\n\u003cbr/\u003e\n\n\n\n## ☢️ What's a Radioactive-State ?\n\nRadioactive state is a **deeply reactive** state.\nWhen it is mutated at any level ( shallow or deep ) it re-renders the component automatically !\n\nNo need to set the state. No need to use libraries like immer.js to produce a new state. No overhead of creating a new state at all! **Just mutate your state, that's it !**\n\n\u003cbr/\u003e\n\n\n\n\n## ✨ Creating a Radioactive State With `useRS` hook\n\n`radioactive-state` gives you a hook `useRS` (use radioactive state) which lets you create a radioactive state in your React Components.\n\n### Examples\n\n\u003e Click on the triangle icon to expand the Example\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\n🍭 \u003cstrong\u003eCounter App\u003c/strong\u003e\n\u003cp align='center'\u003e\n  \u003cimg align='center' src='img/counter.gif' width='450'/\u003e\n\u003c/p\u003e\n\u003c/summary\u003e\n\n\u003c!-- Live Demo --\u003e\n\u003ca href='https://codesandbox.io/s/counter-example-v9bsh?file=/src/Counter.js' target=\"_blank\" title='counter app'\u003e Live Demo \u003c/a\u003e\n\n\u003c!-- Code --\u003e\n```jsx\nimport useRS from 'radioactive-state';\n\nconst Counter = () =\u003e {\n  // create a radioactive state\n  const state = useRS({\n    count: 0,\n  });\n\n  // yep, that's it\n  const increment = () =\u003e state.count++;\n\n  return \u003cdiv onClick={increment}\u003e{state.count}\u003c/div\u003e;\n};\n```\n\u003c/details\u003e\n\u003cbr/\u003e\n\n---\n\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\n\u003cstrong\u003e 🍡 Array Of Counters App \u003c/strong\u003e\n\u003cp align='center'\u003e\n  \u003cimg align='center' src='img/counters.gif' width='450'/\u003e\n\u003c/p\u003e\n\u003c/summary\u003e\n\nLet's take this a step further, Let's make an app that has an array of counters, each of them can be incremented individually and sum of all the counters is displayed too\n\nThis examples shows that deep mutation also triggers a re-render and that **you can use any mutative functions directly**\n\n\u003ca href='https://codesandbox.io/s/counters-example-sctz6?file=/src/Counters.js' target=\"_blank\" title='counter app'\u003e Live Demo \u003c/a\u003e\n\n```jsx\nimport useRS from \"radioactive-state\";\n\nconst Counters = () =\u003e {\n\n  const state = useRS({\n    counts: [0],\n    sum: 0\n  });\n\n  const increment = (i) =\u003e {\n    state.counts[i]++;\n    state.sum++;\n  };\n\n  const addCounter = () =\u003e state.counts.push(0);\n\n  return (\n    \u003c\u003e\n      \u003cbutton onClick={addCounter}\u003e Add Counter \u003c/button\u003e\n      \u003cdiv className=\"counts\"\u003e\n        {state.counts.map((count, i) =\u003e (\n          \u003cdiv className=\"count\" onClick={() =\u003e increment(i)} key={i}\u003e\n            {count}\n          \u003c/div\u003e\n        ))}\n      \u003c/div\u003e\n      \u003cdiv className=\"count sum\"\u003e{state.sum}\u003c/div\u003e\n    \u003c/\u003e\n  );\n};\n```\n\u003c/details\u003e\n\u003cbr /\u003e\n\n\n\n\n## 📺 No Extra Re-Renders, Mutations are Batched\n\nYou might be wondering:\n\n\u003e \"What if I mutate multiple keys in state, Is that going to trigger a re-render component multiple times ?\"\n\n**Nope!** 😉\n\n### Example:\n\n```js\n// suppose you are mutating multiple things in your state in a function doStuff\n\nconst doStuff = () =\u003e {\n  state.a = 200;\n  state.b.x.y.push([10, 20, 30]);\n  state.c++;\n  state.c++;\n  state.c++;\n  delete state.d.e.f;\n  state.e.splice(10, 1);\n  state.f = state.f.filter(x =\u003e x.completed);\n};\n\n// When this function is called\n// it is not **not** going to trigger re-render of component 8 times 😉\n// it will only trigger re-render 1 time! - No extra re-renders! 🤗\n```\n\n#### How is that possible ?\n\nMutations are batched into a one single mutation.\nSo, No matter how many times you mutate the state, it only triggers re-render once\n\nThis allows you to perform a complex mutation in multiple steps without having to worry about re-renders\n\n\u003cdetails\u003e\n\u003csummary\u003e Example \u003c/summary\u003e\n\n```javascript\n\nconst addNewFriend = (newFriendID) =\u003e {\n  const {users, userID} = state\n  const user = users[userID]\n  const newFriend = users[newFriendID]\n  user.friends.push(newFriendID)\n  newFriend.friends.push(userID)\n}\n```\n\n\u003c/details\u003e\n\u003cbr/\u003e\n\n\n\n\n## ⚛ Reactive Props\n\nIn traditional React, Props are considered immutable and mutating them does not trigger re-render. But When using radioactive-state, if you pass a piece of state as a prop to child component, this **child component has the capability to trigger a re-render in parent component** by mutating the prop !\n\nThis can be a **powerful feature**, where **you no longer have to pass functions as props to child component for triggering a re-render in parent component**, which also removes the need to memoize that function\n\n\n### Example: Todos App\n\n\u003c!-- Live Demo --\u003e\n\u003ca href='https://codesandbox.io/s/todos-example-zivos?file=/src/Todos.js' target='_black'\u003e Live Demo \u003c/a\u003e\n\n\u003c!-- Todos GIF --\u003e\n\u003cp align='center'\u003e\n  \u003cimg align='center' src='img/todos.gif' width='350'/\u003e\n\u003c/p\u003e\n\n\n\u003cbr/\u003e\n\n\n\n\n## 🌿 State is always fresh !\n\nUnlike `useState`, `useRS`'s state is always fresh\n\n#### What does that mean ?\n\nWhen you set a new state using `useState`'s setter function, it does not directly change the value of state. value of state is changed only after a re-render. This can cause some weird bugs.\n\nLet's see those problems and see how `radioactive-state` is immune to them.\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ccode\u003euseState\u003c/code\u003e's state is not always fresh \u003c/summary\u003e\n\u003cbr/\u003e\nLet's add Logs before and after the state is set in our counter app.\n\n\u003c!-- Live Demo --\u003e\n\u003ca href='https://codesandbox.io/s/usestate-s-state-is-not-always-fresh-pfzpw?file=/src/App.js' target='_black'\u003e Live Demo \u003c/a\u003e\n\n\u003c!-- Code --\u003e\n```js\nfunction App() {\n  const [state, setState] = useState({\n    count: 0\n  });\n\n  const increment = () =\u003e {\n    console.log(\"before:\", state.count); // before: 0\n    setState({ count: state.count + 1 });\n    console.log(\"after:\", state.count); // after: 0\n  };\n\n  return (\n    \u003cdiv className=\"App\"\u003e\n      \u003cdiv className=\"count\" onClick={increment}\u003e\n        {state.count}\n      \u003c/div\u003e\n    \u003c/div\u003e\n  );\n}\n\n// when increment is called, you would get the same before and after values\n// before: 0\n// after: 0\n\n// we are not getting the fresh state after it is updated,\n// we have to wait for the component to re-render\n\n```\n\u003cbr/\u003e\n\n\n### `useRS` state is always fresh!\n\n`useRS`'s state is mutated directly by the user. So, **No need to wait for a re-render to get the fresh state**.\n\nWith radioactive-state, You can use your state with confidence that whenever you use it, it's gonna be fresh ! 😙\n\n\u003ca href='https://codesandbox.io/s/userss-state-is-always-fresh-jq741?file=/src/App.js' target='_black'\u003e Live Demo \u003c/a\u003e\n\n```js\nfunction App() {\n  const state = useRS({\n    count: 0\n  });\n\n  const increment = () =\u003e {\n    console.log(\"before:\", state.count); // before: 0\n    state.count++;\n    console.log(\"after:\", state.count); // after: 1\n  };\n\n  return (\n    \u003cdiv className=\"App\"\u003e\n      \u003cdiv className=\"count\" onClick={increment}\u003e\n        {state.count}\n      \u003c/div\u003e\n    \u003c/div\u003e\n  );\n}\n\n// works as expected 😄 !\n```\n\n---\n\u003c/details\u003e\n\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ccode\u003euseState\u003c/code\u003e's closure problem \u003c/summary\u003e\n\u003cbr/\u003e\n\nLet's assume that increment function is async and before incrementing the value of count, we have to wait for some async task.\n\nNow guess what happens if you click the counter quickly 3 times?\ncount is only going to increment to 1 instead of 3, even though increment function is called 3 times !\n\n\u003c!-- Live Demo --\u003e\n\u003ca href='https://codesandbox.io/s/usestates-closure-problem-x6g28?file=/src/App.js' target='_black'\u003e Live Demo \u003c/a\u003e\n\n\u003c!-- Code --\u003e\n```js\nfunction App() {\n  const [state, setState] = useState({\n    count: 0\n  });\n\n  // click the button 3 times quickly so increment will be called 3 times\n  // but all three times, it will use the same old value of count\n  const increment = async () =\u003e {\n    await someAsyncTask();\n    setState({ count: state.count + 1 });\n  };\n\n  return (\n    \u003cdiv className=\"App\"\u003e\n      \u003cdiv className=\"count\" onClick={increment}\u003e\n        {state.count}\n      \u003c/div\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\nThis happens because setCount keeps using old value of count until the component re-renders.\nThis is because increment function \"closes over\" the count when it was defined.\n\nTo fix this issue, you update the state using a function like this:\n\n```js\n// passing new state instead of function that creates new state fixes this issue\nsetCount(prevState =\u003e {\n  return {\n    count: prevState.count + 1\n  }\n})\n```\n\nThis gets awkward and complicated really fast as your state becomes more complex.\n\u003cbr/\u003e\n\n### `useRS` fixes this issue !\n\n\u003ca href='https://codesandbox.io/s/users-solves-the-closure-problem-2iys5?file=/src/App.js' target='_black'\u003e Live Demo \u003c/a\u003e\n\nIf you click the button 3 times quickly, count will  increment from 0 to 3. It works as expected 🙌\n\n```js\nfunction App() {\n  const state = useRS({\n    count: 0\n  });\n\n  const increment = async () =\u003e {\n    await someAsyncTask();\n    state.count++; // works as expected !\n  };\n\n  return (\n    \u003cdiv className=\"App\"\u003e\n      \u003cdiv className=\"count\" onClick={increment}\u003e\n        {state.count}\n      \u003c/div\u003e\n    \u003c/div\u003e\n  );\n}\n```\n---\n\u003c/details\u003e\n\n---\n\n\u003cbr/\u003e\n\n\n\n## ⚡ Radioactive State is blazing fast !\n\n`useRS` is **25% faster** than `useState` for an a fairly Complex React App.\n\n\u003e This number is derived from an average of 100 performance tests where an array of 200 objects is rendered and various operations like adding, removing, re-ordering and mutations were done one after another.\n\nNote that, `useRS` **keeps getting faster and faster** compared to useState if you keep increasing the complexity of state, **even more than 25%**\nBut, **for a simple web app**, both will have about the **same performance** where state of a component is not that complex.\n\n### Why `useRS` is faster than `useState` ?\n\nIn the case of `useState`, every time you want to update the state, you have to create a new state and call setter function with the new state.\n\nBut, In the case of `radioactive-state` **you don't have to create a new state**, you just mutate the state and that's it. radioactive-state **does not create a new state** under the hood either. There are other optimizations as well, which makes sure no extra work is done, no extra re-renders are triggered.\n\n\u003cbr/\u003e\n\n\n\n\n## 🧬 Reactive bindings for inputs\n\n\u003cdetails\u003e\n\u003csummary\u003e You can create a controlled input the old way like this \u003c/summary\u003e\n\n### using the `useState`\n\n\u003c!-- code --\u003e\n```jsx\nconst [input, setInput] = useState(\"type something\");\n\n\u003cinput\n  value={input}\n  onChange={(e) =\u003e setInput(e.target.value)}\n  type='text'\n/\u003e\n```\n\n### using the `useRS`\n\n```jsx\n// creating state\nconst state = useRS({\n  input: ''\n})\n\n\u003cinput\n  value={state.input}\n  onChange={(e) =\u003e state.input = e.target.value}\n  type='text'\n/\u003e\n```\n\nBoth are fairly easy but becomes annoying if you have a form with multiple inputs\n\nYou would also have to convert string to number if the input is type 'number' or 'range'.\nYou would also need to use 'checked' prop instead of 'value' for checkboxes and radios\n\n---\n\u003c/details\u003e\n\u003cbr/\u003e\n\n\nRadioactive State provides a binding API that lets you bind an input's value to a key in state.\n\nTo bind `state.key` to an input you prefix the key with $ - `state.$key` and then spread over the input. that's it ! 😮\n\n```js\n\u003cinput {...state.$key}  /\u003e\n```\n\nThis works because, `state.key` returns the value but `state.$key` returns an object containing value and onChange props, which we are spreading over input\n\n\u003cbr/\u003e\n\n### Bindings takes care of different types of inputs\n\nBindings **rely on initial value of the key** in state to figure out what type of input it is\n\nif the initial value is a type of `string` or `number`, `state.$key` returns object containing `value` and `onChange`\n\nIf the initial value is type of `boolean`, `state.$key` returns an object containing `checked` and `onChange` props and uses `e.target.checked` internally in the onChange function\n\nIf the initial value type of `number`, onChange function converts the `e.target.value` from `string` to `number` then saves it in the key.\n\n#### Example\n\n\u003c!-- Live Demo --\u003e\n\u003ca href='https://codesandbox.io/s/reactive-bindings-all-types-dleod?file=/src/App.js' target=\"_blank\" title='counter app'\u003e Live Demo \u003c/a\u003e\n\n\u003c!-- Bindings GIF --\u003e\n\u003cp align='center'\u003e\n  \u003cimg src='./img/form.gif' width='300'\u003e\n\u003c/p\u003e\n\n\u003c!-- code --\u003e\n```jsx\nconst state = useRS({\n  a: 69,\n  b: 420,\n  c: \"Hello\",\n  d: \"Write something here\",\n  e: true,\n  f: \"bar\"\n});\n\nconst { $a, $b, $c, $d, $e, $f } = state;\n\nreturn (\n  \u003cdiv className=\"App\"\u003e\n    \u003cpre\u003e {JSON.stringify(state, null, 2)}\u003c/pre\u003e\n    \u003cinput {...$a} type=\"number\" /\u003e\n    \u003cinput {...$b} type=\"range\" min=\"0\" max=\"1000\" /\u003e\n    \u003cinput {...$c} type=\"text\" /\u003e\n    \u003ctextarea {...$d} /\u003e\n    \u003cinput {...$e} type=\"checkbox\" /\u003e\n    \u003cselect {...$f}\u003e\n      \u003coption value=\"foo\"\u003e foo \u003c/option\u003e\n      \u003coption value=\"bar\"\u003e bar \u003c/option\u003e\n      \u003coption value=\"baz\"\u003e baz \u003c/option\u003e\n    \u003c/select\u003e\n  \u003c/div\u003e\n);\n\n```\n\u003cbr/\u003e\n\n\n\n\n## Dealing with expensive initial State\n\nIf initial State is a result of doing some expensive calculation, (for example, getting the initial State from localStorage), It would be very inefficient to directly call it like this\n\n```javascript\nconst state = useRS({\n  x: getX(); // assume that getX is an expensive function\n})\n```\n\nThis is inefficient because getX runs every time the component renders.\nThis is not what we want. We just want to call `getX` only once to get the initial state.\n\nTo fix this you can just pass the function as initial State, without calling it.\nThis is similar to what we do in useState\n\n#### `useState`\n```javascript\nconst [x, setX] = useState(getX)\n```\n\n#### `useRS`\n```javascript\nconst state = useRS({\n  x: getX\n})\n```\n\nThis is valid for entire state tree as well\n\n\u003c!-- code --\u003e\n```javascript\n// assume that getState function when called returns the initial State\n\nconst state = useRS(getState)\n```\n\nThis also valid for any deeply nested key in the state tree\n\n\u003c!-- code --\u003e\n```javascript\n// assume that getD is a function which when called returns the initial value of d\n\nconst state = useRS({\n  a: 100\n  b: {\n    c: {\n      d: getD\n    }\n  }\n})\n```\n\u003cbr/\u003e\n\n\n\n\n\n## ⛳ Mutation flag\n\nIf we mutate a reference type data in state such as array or an object, it's reference stays the same. This can create problems If you want to run some effect when it is mutated.\n\n**Example**\n\n\u003c!-- code --\u003e\n```javascript\nconst state = useRS({\n  todos: []\n})\n\n// when addTodo is called, it would trigger a re-render\n// but the effect would not run because todos is mutated, its reference is same\nuseEffect( () =\u003e {\n  console.log('todos changed to', state.todos)\n}, [state.todos])\n\n\nconst addTodo = (todo) =\u003e state.todos.push(todo)\n```\n\nThis happens because useEffect uses `===` to check whether the dependencies changed or not. To fix this, instead of adding `state.todos` in dependency array add `state.todos.$`\n\n### `state.key.$`\n\n`state.key.$` is a number which is increment by some amount when key is mutated. So, `state.key.$` works a mutation flag for `state.key`\n\n**Example**\n\n\u003c!-- code --\u003e\n```javascript\nconst state = useRS( { todos: [] })\n\nuseEffect( () =\u003e {\n  console.log('todos changed to', state.todos) // works !\n}, [state.todos.$]) // eslint-disable-line\n```\n\nIf you have ESlint setup, it will complain about not adding `state.todos` in the dependency array. You can fix it by disabling eslint for that particular line.\n\n**Note** that **this is only necessary of reference type data**, don't do this for value types such as number, strings, boolean etc. because value types are immutable and they are re-assigned a new value, they are not mutated.\n\n\u003c!-- code --\u003e\n```javascript\nconst state = useRS({\n  count: 0\n})\n\n// works\nuseEffect( () =\u003e {\n  console.log('count changed to', state.count)\n}, [state.count])\n\n// count is actually assigned a new value, it is not mutated\n// count++ is count = count + 1\nconst increment = () =\u003e state.count++\n```\n\u003cbr/\u003e\n\n\n\n\n## ❓ FAQs\n\n\u003c!-- faq 1 --\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCan I use useRS hook more than once ? \u003c/summary\u003e\n\u003cbr/\u003e\n\n**Yes.** You don't have to put all of the state of the component inside the state object. You can use the hook more than once.\n\n#### Example\n\n```javascript\nconst todos = useRS([])\nconst form = useRS({\n  name: '',\n  age: 0,\n})\n```\n\nWhile this is okay, **I would advise you to not do this**, Because putting all of state in one object gives you **better *performance** in the case of radioactive-state. (because of better mutation batching)\n\nIt would also be **hard to store simple value types**, because simple value types can not be mutated and so you would need to wrap it inside an object.\n\n#### Example\n\n```javascript\nconst count = useRS(0) // invalid, gives error ❌\n```\n\n```javascript\nconst count = useRS( { value: 0 }) // works ✅\n```\n\nThis would also make creating reactive bindings awkward. That's why it is **strongly recommended to store all the state into a single object** by using useRS only once !\n\n---\n\u003c/details\u003e\n\n\n\u003c!-- FAQ 2 --\u003e\n\u003cdetails\u003e\n\u003csummary\u003e Is this magic, How does it work ? \u003c/summary\u003e\n\u003cbr/\u003e\nradioactive-state uses **JavaScript Proxy** to create a deeply reactive state by recursively proxifying the state. Whenever a mutation occurs in the state tree, a function is called with information about where the mutation took place which schedules an async re-render to update the component to reflect the changes in state to UI.\n\u003c/details\u003e\n\u003cbr/\u003e\n\n\n\n\n## 💙 Contributing\n\nPR's are welcome !\n\nFound a Bug ? Create an Issue.\n\nChat on [Slack](https://join.slack.com/t/radioactive-state/shared_invite/zt-gwd1rsvr-vkoizw5RG5rk9rwsdgT3gQ)\n\n\u003cbr/\u003e\n\n\n\n\n## 💖 Like this project ?\n\nLeave a ⭐ If you think this project is cool.\n\n[Share with the world](https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2FMananTank%2Fradioactive-state\u0026via=MananTank_\u0026text=Make%20your%20@react%20App%20Truly%20Reactive%20with%20radioactive-state\u0026hashtags=react%2CradioactiveState) ✨\n\n\u003cbr/\u003e\n\n\n\n\n## 👨‍💻 Author\n\n### Manan Tank\n\n[Twitter](https://twitter.com/MananTank_ \"Manan Tank\")\n\n\u003cbr/\u003e\n\n\n\n\n## 🍁 Licence\n\n**ISC**","funding_links":[],"categories":["JavaScript","Examples"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMananTank%2Fradioactive-state","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMananTank%2Fradioactive-state","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMananTank%2Fradioactive-state/lists"}