{"_id":"eslint-plugin-use-encapsulation","_rev":"7-191a44f6205766dd871e861cfcb07e12","name":"eslint-plugin-use-encapsulation","dist-tags":{"latest":"1.3.1"},"versions":{"1.0.0":{"name":"eslint-plugin-use-encapsulation","version":"1.0.0","keywords":["eslint","eslintplugin","React","Hooks"],"author":{"url":"https://kyleshevlin.com","name":"Kyle Shevlin","email":"kyle.a.shevlin@gmail.com"},"license":"MIT","_id":"eslint-plugin-use-encapsulation@1.0.0","maintainers":[{"name":"kyleshevlin","email":"kyle.a.shevlin@gmail.com"}],"dist":{"shasum":"351b4c6adac4a2eb54a604e0f62edb2a2dfec39c","tarball":"https://registry.npmjs.org/eslint-plugin-use-encapsulation/-/eslint-plugin-use-encapsulation-1.0.0.tgz","fileCount":18,"integrity":"sha512-OH0BVVT+7XkcGHf7v2chzMHqjWy1ddCBFaAk+N+ZP3I1NaebIOkuFPq0NSJyz09KvPFZYZFSqje+tg9jsZ/tZQ==","signatures":[{"sig":"MEYCIQCz308tZ6hKPQr9xLE/rX9zd+av1xv8Ucf+e78A/ujx/wIhANOfpIYlJMoVRp+ORmKoYQftYsw0hPSH2L4QKcqOMkVT","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":178627,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh2qPnCRA9TVsSAnZWagAAjMsP/1YzYLnZUH2zH7/nC811\nXcZI/DRXboC53knG+MknuYQekBJ4vYno6zf3aNHp5pS8AwDo7e4KQZbXwxHx\n8PUgnjE/ZpT7yIJAevYGPF2sb2w1fLxNsSaGv2+DXK8UEVbkalF1jJe61omd\nn5qGhJ1zctLAhiAhg4KDa3z0u71jER11Ijly1AU21BPp+Nfhf4Nr4k8V3mIj\no/y/OJYfdMHmZnL8xBb5jGLnXZOepEtTb9/F+q6gtoEwjyMfeTZNlTjNlLXm\nCd7UbUbvmhMrYowVJFgqkk31zNyrupDBahK0JQ3STWGO0z5XxA/zAqkMR6WF\nH2oDy8dauRJMvue7R7YlmAeLvzaF5PVUhUoun7BXdlzGR/xwcIiiaUFeiofm\n9lyTdHPIyrk2t9hMW73xwd+w6RWywDO58OdodZlTOQP+yVnD6n0BE1YnWgKs\nD5ZgHwimLh5ROZeKYkL409g1FhbZYa9GeHwkgIvBIlCZW1HMtaz5530zF1tp\n/5/19tCK+V4IPGRbe9xaeZygxcO4YB3Rzald3H2Cpxfj8ONgcdvpfOYN/rmV\n3u2OvawnviUSBKfvmCmiu/Bhp9e/5xpxt6QC9SFQ3nWSQjwYMQv2hLjUqfQX\nOR1+1iABosR6CGnhbPI6JBEb4YcNCd7/Mr1ff2tDABztRhzD79Qvi+fZo7Om\nSkTU\r\n=TOID\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","scripts":{"test":"jest","test:watch":"jest --watch"},"_npmUser":{"name":"kyleshevlin","email":"kyle.a.shevlin@gmail.com"},"repository":{"url":"git@github.com:kyleshevlin/eslint-plugin-use-encapsulation.git","type":"git"},"description":"An ESLint rule to encourage using custom hook abstractions","directories":{},"licenseText":"Copyright 2021 Kyle Shevlin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^26.6.3","eslint":"^7.17.0"},"peerDependencies":{"eslint":">=0.8.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-plugin-use-encapsulation_1.0.0_1634836318177_0.16587733852775055","host":"s3://npm-registry-packages"}},"1.1.0":{"name":"eslint-plugin-use-encapsulation","version":"1.1.0","keywords":["eslint","eslintplugin","React","Hooks"],"author":{"url":"https://kyleshevlin.com","name":"Kyle Shevlin","email":"kyle.a.shevlin@gmail.com"},"license":"MIT","_id":"eslint-plugin-use-encapsulation@1.1.0","maintainers":[{"name":"kyleshevlin","email":"kyle.a.shevlin@gmail.com"}],"dist":{"shasum":"a7a155c181f9cf1ad41e825916fcb10c04eaffe2","tarball":"https://registry.npmjs.org/eslint-plugin-use-encapsulation/-/eslint-plugin-use-encapsulation-1.1.0.tgz","fileCount":18,"integrity":"sha512-pYRh3krpHLPiYDOpmwuCSlmc4nbK4rGnepcpiLhxdal5fO8mfWVsS74NmMnxTMwOPmTAJTp6klBHukuvXp7I7A==","signatures":[{"sig":"MEQCIBPDVu7btUCVcUcWsQYWmdE8Rf1fABRRIPrDLeQ7UgukAiAkp9tjvPi2kFpyNJV0HJwZdOAqtpsZzpLhL3B8tQ4Xhg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":182336,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiWvAmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpyqRAAjRJ9UwN24mwxgDuWcMIQkQD35MYjnYCjjxXUxOvV5qxen9uH\r\nKI3UANFue0GwNYx1T5what8b9M0h5EC00wMhi1QXb8U9nfOPwngq9IdWG4AF\r\nTFObKsR4Dgpdvu+ssnf9j9KzviFn85tcRqG/n4D+JZ/Lr8BbsJc4k7MqzmA1\r\ngBGrbYLD1NGR1JCljUrxLDHBpdlq9uVuI5L3A7ZToLFmxq0RzBF+DCrxy8lv\r\nptjSVZiHZU/chdwq4uWt4OZ1wizyN1OaNHbAmBNE70j0GJFaWjOhlJs0y4Qw\r\n6fZDK1zNJhuHjOau8F1fZxZ1mxNnxxvI28f4wmSeiNubukJGhPO3s/aamoIU\r\n5X+oT1/C6b8JH+D6pLl3tMRZKF7UIpgT6B89zmNewssomL3VPm0E7weAwpL2\r\nwbT6VwLS52hI2H1VfBohmC8e52vhFm4Vv0070sBtqsjc5jsf80k5E1ffVa4F\r\neVrd9IsS3Y2Y7F13oPkFJbCVThSHOgeR/smDGV9QK5WF5UEMaELSsGzF/Ecp\r\nGFC+MO17n+eBDk1xst1Qhciv4MmJq8HjvtUT5X2t7Ch6HhYj305IwuE44C2K\r\nugaHxvkKQcB6ACs9WrRhVhFdoSczgIlu27iiY4K4x8YGkGiNp1JMavPfao8s\r\n9Exq2j08dbTc9pDyz7c3edUhu/pc0w7dFBU=\r\n=aC0A\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","scripts":{"test":"jest","test:watch":"jest --watch"},"_npmUser":{"name":"kyleshevlin","email":"kyle.a.shevlin@gmail.com"},"repository":{"url":"git@github.com:kyleshevlin/eslint-plugin-use-encapsulation.git","type":"git"},"description":"An ESLint rule to encourage using custom hook abstractions","directories":{},"licenseText":"Copyright 2021 Kyle Shevlin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^26.6.3","eslint":"^7.17.0"},"peerDependencies":{"eslint":">=0.8.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-plugin-use-encapsulation_1.1.0_1650126885911_0.38692045824483","host":"s3://npm-registry-packages"}},"1.2.0":{"name":"eslint-plugin-use-encapsulation","version":"1.2.0","keywords":["eslint","eslintplugin","React","Hooks"],"author":{"url":"https://kyleshevlin.com","name":"Kyle Shevlin","email":"kyle.a.shevlin@gmail.com"},"license":"MIT","_id":"eslint-plugin-use-encapsulation@1.2.0","maintainers":[{"name":"kyleshevlin","email":"kyle.a.shevlin@gmail.com"}],"dist":{"shasum":"fbd2c15f3d7dcaf671127df152e8cbec317376e6","tarball":"https://registry.npmjs.org/eslint-plugin-use-encapsulation/-/eslint-plugin-use-encapsulation-1.2.0.tgz","fileCount":18,"integrity":"sha512-KM1Fcp+1GJbeqmgc2IUk5Tcb4t/AcACWObvyRi46d8u0EeDw6ge4LyYv8eHMOyPpmZsMUAQh627WUQOY/bHypg==","signatures":[{"sig":"MEUCICT7Q6m3wbwh/BszpQUGqlPlJQAlGwQQ1NPxQ5c4nf/vAiEA2Prn41nMsokNEjbSJ83Wba+QYZUhwFbMTOX/1zOA6L8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":183767},"main":"index.js","scripts":{"test":"jest","test:watch":"jest --watch"},"_npmUser":{"name":"kyleshevlin","email":"kyle.a.shevlin@gmail.com"},"repository":{"url":"git@github.com:kyleshevlin/eslint-plugin-use-encapsulation.git","type":"git"},"description":"An ESLint rule to encourage using custom hook abstractions","directories":{},"licenseText":"Copyright 2021 Kyle Shevlin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^26.6.3","eslint":"^7.17.0"},"peerDependencies":{"eslint":">=0.8.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-plugin-use-encapsulation_1.2.0_1735247065816_0.9883750938545555","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"eslint-plugin-use-encapsulation","version":"1.3.0","keywords":["eslint","eslintplugin","React","Hooks"],"author":{"url":"https://kyleshevlin.com","name":"Kyle Shevlin","email":"kyle.a.shevlin@gmail.com"},"license":"MIT","_id":"eslint-plugin-use-encapsulation@1.3.0","maintainers":[{"name":"kyleshevlin","email":"kyle.a.shevlin@gmail.com"}],"dist":{"shasum":"698e0e4e4f00e9a4253431a7ef895769ae81d692","tarball":"https://registry.npmjs.org/eslint-plugin-use-encapsulation/-/eslint-plugin-use-encapsulation-1.3.0.tgz","fileCount":10,"integrity":"sha512-7vJxhUJT0hUPxg0JG5wRikdPvS+9IRkIWJtd4C43k1webJwuAVAl3JthBXiQq9yDQrjSrUQPz0oYBJFsW65mxQ==","signatures":[{"sig":"MEUCIEaNOB6pHjweK+iSbvMFkkFErmchxIxJ5r6Dbrqlo7JlAiEAmSQPE44mYPP4i8HiQ1Stg0XEDyNBQqt28paFyCgdtx8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":9622},"main":"index.js","type":"module","exports":{".":"./index.js"},"scripts":{"test":"node --experimental-vm-modules node_modules/jest/bin/jest.js","release":"npx np","test:watch":"node --experimental-vm-modules node_modules/jest/bin/jest.js --watch"},"_npmUser":{"name":"kyleshevlin","email":"kyle.a.shevlin@gmail.com"},"repository":{"url":"git@github.com:kyleshevlin/eslint-plugin-use-encapsulation.git","type":"git"},"description":"An ESLint rule to encourage using custom hook abstractions","directories":{},"licenseText":"Copyright 2021 Kyle Shevlin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^7.17.0"},"peerDependencies":{"eslint":">=0.8.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-plugin-use-encapsulation_1.3.0_1739292470171_0.9561247090637393","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"eslint-plugin-use-encapsulation","version":"1.3.1","description":"An ESLint rule to encourage using custom hook abstractions","main":"./dist/index.js","module":"./dist/index.mjs","type":"module","exports":{".":{"import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"build":"tsup","release":"npx np","test":"node --experimental-vm-modules node_modules/jest/bin/jest.js","test:watch":"node --experimental-vm-modules node_modules/jest/bin/jest.js --watch","prepublishOnly":"yarn build"},"keywords":["eslint","eslintplugin","React","Hooks"],"author":{"name":"Kyle Shevlin","email":"kyle.a.shevlin@gmail.com","url":"https://kyleshevlin.com"},"repository":{"type":"git","url":"git@github.com:kyleshevlin/eslint-plugin-use-encapsulation.git"},"license":"MIT","publishConfig":{"access":"public"},"peerDependencies":{"eslint":">=0.8.0"},"devDependencies":{"eslint":"^7.17.0","jest":"^29.7.0","tsup":"^8.3.6","typescript":"^5.7.3"},"licenseText":"Copyright 2021 Kyle Shevlin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"eslint-plugin-use-encapsulation@1.3.1","dist":{"shasum":"c027d8bd1bf87c938bf5a15e40ecbd5709081760","integrity":"sha512-Eig6O2wq0JBxLRPg4d0i61QThNxC3eAoBevOecvjk8Jk/43bCLwWM7AzFkOR0shehczrcJaOttjI5dNEnD5RRQ==","tarball":"https://registry.npmjs.org/eslint-plugin-use-encapsulation/-/eslint-plugin-use-encapsulation-1.3.1.tgz","fileCount":7,"unpackedSize":12353,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEIIyOOwrPCebdv/X+dDl/+WSOgdgnqeV754W2NpvDdFAiEAxmyg0XaCnfV6VxdmNcoW8nYM8kj1yx9XeLgU9uLijCI="}]},"_npmUser":{"name":"kyleshevlin","email":"kyle.a.shevlin@gmail.com"},"directories":{},"maintainers":[{"name":"kyleshevlin","email":"kyle.a.shevlin@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/eslint-plugin-use-encapsulation_1.3.1_1741461113596_0.46540660651282373"},"_hasShrinkwrap":false}},"time":{"created":"2021-10-21T17:11:58.125Z","modified":"2025-03-08T19:11:53.970Z","1.0.0":"2021-10-21T17:11:58.361Z","1.1.0":"2022-04-16T16:34:46.166Z","1.2.0":"2024-12-26T21:04:26.042Z","1.3.0":"2025-02-11T16:47:50.372Z","1.3.1":"2025-03-08T19:11:53.778Z"},"author":{"name":"Kyle Shevlin","email":"kyle.a.shevlin@gmail.com","url":"https://kyleshevlin.com"},"license":"MIT","keywords":["eslint","eslintplugin","React","Hooks"],"repository":{"type":"git","url":"git@github.com:kyleshevlin/eslint-plugin-use-encapsulation.git"},"description":"An ESLint rule to encourage using custom hook abstractions","maintainers":[{"name":"kyleshevlin","email":"kyle.a.shevlin@gmail.com"}],"readme":"# eslint-plugin-use-encapsulation\n\nThis ESLint plugin contains a single rule:\n\n- `prefer-custom-hooks`\n\nThis rule does not allow using the hooks provided by the React library directly inside a component. They can only be used by custom hooks, encouraging the use of custom hooks in your components. The abstraction of a custom hook follows the \"useEncapsulation\" pattern for React Hooks: [https://kyleshevlin.com/use-encapsulation](https://kyleshevlin.com/use-encapsulation)\n\n## Installation\n\nInstall the plugin: `npm install --save-dev eslint-plugin-use-encapsulation` or `yarn add -D eslint-plugin-use-encapsulation`.\n\n## Configuration\n\n### ESLint 9 Flat Config\n\n```js\nimport eslintPluginUseEncapsulation from 'eslint-plugin-use-encapsulation'\n\nexport default [\n  {\n    plugins: {\n      'use-encapsulation': eslintPluginUseEncapsulation,\n    },\n    rules: {\n      'use-encapsulation/prefer-custom-hooks': [\n        'error',\n        {\n          allow: ['useMemo'], // optional\n          block: ['useMyCustomHook'], // optional\n        },\n      ],\n    },\n  },\n]\n```\n\n### ESLint 8 (Legacy)\n\n```json\n{\n  \"plugins\": [\"use-encapsulation\"],\n  \"rules\": {\n    \"use-encapsulation/prefer-custom-hooks\": [\n      \"error\",\n      {\n        \"allow\": [\"useMemo\"], // optional\n        \"block\": [\"useMyCustomHook\"] // optional\n      }\n    ]\n  }\n}\n```\n\n## The Philosophy\n\n### Bad\n\nHere we are using React Hooks directly inside a component with no custom hook abstraction.\n\n```jsx\nfunction Counter() {\n  const [state, setState] = React.useState(0)\n\n  const inc = React.useCallback(() => {\n    setState(s => s + 1)\n  })\n\n  const dec = React.useCallback(() => {\n    setState(s => s - 1)\n  })\n\n  const reset = React.useCallback(() => {\n    setState(0)\n  })\n\n  return (\n    <div>\n      <div>Count: {state}</div>\n      <div>\n        <button type=\"button\" onClick={inc}>\n          +\n        </button>\n        <button type=\"button\" onClick={dec}>\n          -\n        </button>\n        <button type=\"button\" onClick={reset}>\n          reset\n        </button>\n      </div>\n    </div>\n  )\n}\n```\n\n### Good\n\nHere we abstract the functionality into a custom hook, encapsulating the concerns of `state` and its `handlers` together.\n\n```jsx\nfunction useCounter(initialState = 0) {\n  const [state, setState] = React.useState(initialState)\n\n  const handlers = React.useMemo(\n    () => ({\n      inc: () => {\n        setState(s => s + 1)\n      },\n      dec: () => {\n        setState(s => s - 1)\n      },\n      reset: () => {\n        setState(initialState)\n      },\n    }),\n    [initialState]\n  )\n\n  return [state, handlers]\n}\n\nfunction Counter() {\n  const [state, { inc, dec, reset }] = useCounter()\n\n  return (\n    <div>\n      <div>Count: {state}</div>\n      <div>\n        <button type=\"button\" onClick={inc}>\n          +\n        </button>\n        <button type=\"button\" onClick={dec}>\n          -\n        </button>\n        <button type=\"button\" onClick={reset}>\n          reset\n        </button>\n      </div>\n    </div>\n  )\n}\n```\n\n## The Practical\n\n### Fail\n\n```javascript\nfunction MyComponent() {\n  React.useEffect(() => {})\n  return null\n}\nfunction MyComponent() {\n  useEffect(() => {})\n  return null\n}\nconst MyComponent = () => {\n  React.useEffect(() => {})\n  return null\n}\nconst MyComponent = () => {\n  useEffect(() => {})\n  return null\n}\n```\n\n### Pass\n\n```javascript\nfunction useMyCustomHook() { React.useEffect(() => {})) }\nfunction useMyCustomHook() { useEffect(() => {})) }\nconst useMyCustomHook = () => { React.useEffect(() => {})) }\nconst useMyCustomHook = () => { useEffect(() => {})) }\nfunction MyComponent() { useMyCustomHook(); return null }\nconst MyComponent = () => { useMyCustomHook(); return null }\n```\n\n## Options\n\nThere are two options for `prefer-custom-hooks`: an `allow` list, and a `block` list.\n\n### `allow`\n\nWhile it is not recommended, the `allow` list is an array of React hooks that will be exempted from triggering the rule. For example, you may want to allow `useMemo` to be used directly in components. You can set that up like so:\n\n```json\n{\n  \"plugins\": [\"use-encapsulation\"],\n  \"rules\": {\n    \"use-encapsulation/prefer-custom-hooks\": [\"error\", { \"allow\": [\"useMemo\"] }]\n  }\n}\n```\n\nIt is recommended that you use the `allow` option sparingly. It is likely wiser to use the occasional `eslint-disable` than to allow a particular hook throughout your project.\n\n### `block`\n\nOn the other hand, the `block` list is an array of additional custom hooks that you would like to prevent from being used directly in a component. Perhaps you have a custom hook that really should be encapsulated with other hooks. Add it to the block list like so:\n\n```json\n{\n  \"plugins\": [\"use-encapsulation\"],\n  \"rules\": {\n    \"use-encapsulation/prefer-custom-hooks\": [\n      \"error\",\n      { \"block\": [\"useMyCustomHook\"] }\n    ]\n  }\n}\n```\n\n## Further Reading\n\nI discuss this concept in depth in my [useEncapsulation](https://kyleshevlin.com/use-encapsulation) blog post.\n","readmeFilename":"README.md"}