{"id":22415364,"url":"https://github.com/esau-morais/react-hooks","last_synced_at":"2026-05-05T21:39:02.349Z","repository":{"id":40752286,"uuid":"293161332","full_name":"esau-morais/react-hooks","owner":"esau-morais","description":"⚛️ Most important React Hooks and examples","archived":false,"fork":false,"pushed_at":"2023-01-07T05:02:40.000Z","size":4279,"stargazers_count":1,"open_issues_count":9,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-01T09:25:13.270Z","etag":null,"topics":["custom-hook","custom-hooks","hooks","react-functions","react-hooks","reacthooks","reactjs","usecallback","usecontext","useeffect","usememo","usereducer","useref","usestate","usestate-hook"],"latest_commit_sha":null,"homepage":"react-hooks.emmorais.vercel.app","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/esau-morais.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-09-05T22:04:52.000Z","updated_at":"2023-01-03T16:03:37.000Z","dependencies_parsed_at":"2023-02-06T12:31:51.431Z","dependency_job_id":null,"html_url":"https://github.com/esau-morais/react-hooks","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/esau-morais%2Freact-hooks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esau-morais%2Freact-hooks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esau-morais%2Freact-hooks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esau-morais%2Freact-hooks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/esau-morais","download_url":"https://codeload.github.com/esau-morais/react-hooks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245779486,"owners_count":20670688,"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":["custom-hook","custom-hooks","hooks","react-functions","react-hooks","reacthooks","reactjs","usecallback","usecontext","useeffect","usememo","usereducer","useref","usestate","usestate-hook"],"created_at":"2024-12-05T15:12:03.363Z","updated_at":"2026-05-05T21:38:57.318Z","avatar_url":"https://github.com/esau-morais.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Hooks\r\n\r\n![React + Hooks](https://miro.medium.com/max/1000/1*12rLQ2fkPvG76qUF8xH6OQ.png)\r\n\r\n## Table of Content\r\n\r\n- [About](#about)\r\n- [Folder structure](#folder-structure)\r\n- [Installation](#how-do-i-start)\r\n- [useState](#usestate)\r\n- [useEffect](#useeffect)\r\n- [useContext](#usecontext)\r\n- [useReducer](#usereducer)\r\n- [useCallback](#usecallback)\r\n- [useMemo](#usememo)\r\n- [useRef](#useref)\r\n- [Custom hooks](#custom-hooks)\r\n\r\n## About\r\n\r\nA couple of months ago, I started to review every single subject in (Vanilla) JavaScript and React. So, this repository highlights some of the **most important concepts** I've learned about React Hooks. Below you'll find **examples**, a **quick summary** to understand how it works, and a **interactive code** (created using StoryBook).\r\n\r\n## Folder structure\r\n\r\n```\r\nReact-Hooks\r\n│   ...\r\n│\r\n└───src\r\n|   |\r\n│   │   App.js\r\n│   │   index.js\r\n│   │\r\n│   └───(custom) hooks\r\n│   |   │   \r\n│   |   │   \r\n│   |   └───(n custom hooks examples)\r\n│   |\r\n│   └───components\r\n│       │   \r\n│       │   \r\n│       └───(separated hooks folder)\r\n│       │   │\r\n│       │   │\r\n│       │   └───(n examples by folder)\r\n```\r\n\r\n## How do I start?\r\n\r\nYou can interact with the code forking the repository\r\n\r\n\r\n1. Fork this project\r\n\r\n![Forking the project](https://camo.githubusercontent.com/6f03010c651d060f8b7cfc17da7098c1757c4ead/68747470733a2f2f6669727374636f6e747269627574696f6e732e6769746875622e696f2f6173736574732f526561646d652f666f726b2e706e67)\r\n\r\n2. Clone the forked repository\r\n\r\n    `git clone https://github.com/user/React-Hooks` (if you use `git`)\r\n\r\n    or\r\n\r\n    `gh repo clone https://github.com/user/React-Hooks` (if you use `gh` cli)\r\n\r\n3. Install the dependencies\r\n\r\n    `npm install` (if you use `npm`)\r\n\r\n    or\r\n\r\n    `yarn` (if you use   `yarn`)\r\n\r\n4. Start the project\r\n\r\n    `npm start` (if you `npm`)\r\n\r\n    or\r\n\r\n    `yarn start` (if you use `yarn`)\r\n\r\n:warning: To make your learning process better, follow these steps:\r\n\r\n- See the quick summary of each Hook\r\n- See the examples\r\n- Interact with the code and try different ways/examples\r\n\r\n## Hooks rules\r\n\r\n:warning: Before you start, you need to always remember these rules when you call a React Hook:\r\n\r\n- _\"Only call Hooks at the top level\"_\r\n\r\n  Don't call Hooks inside loops, conditions, or nested functions\r\n\r\n- _\"Only call Hooks from React functions\"_\r\n\r\n  Call them from within React functional components and not just any regular JavaScript function\r\n\r\n## Most important React Hooks\r\n\r\n### useState\r\n\r\n#### Quick summary\r\n\r\n- The `useState` hook lets you add state to functional components\r\n- In classes, the state is always an object\r\n- With the useState hook, the state doesn't have to be an object\r\n- The `useState` hook returns an array with 2 elements\r\n  - The first element is the current value of the state, and the second is a state setter function\r\n- New state value depends on the previous state value? You can pass a function to setter function\r\n- When dealing with objects or arrays, always make sure to spread your state variable and then call the setter function\r\n\r\nTo understand better, see the example below or interact with the code forking the project\r\n\r\n```js\r\n// 1️⃣  Import useState Hook\r\n// ⚠️  Remember that we are using React v17, so you don't need to import \"React\" anymore\r\nimport { useState } from 'react';\r\n\r\nfunction UseStateExample() {\r\n  // 2️⃣  Declare a new a statement variable and its function\r\n  // The \"count\" will have a initial value: 0\r\n  const [count, setCount] = useState(0);\r\n  \r\n  return (\r\n    \u003c\u003e\r\n      {/* 3️⃣  Call the statement variable \"count\"\r\n          And its function that will increase 1 on click\r\n      */}\r\n      \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003e\r\n        Count {count}\r\n      \u003c/button\u003e\r\n    \u003c/\u003e\r\n  )\r\n}\r\n```\r\n\r\n[More about useState Hook](https://reactjs.org/docs/hooks-state.html)\r\n\r\n[🔝 Back to Top](#table-of-content)\r\n\r\n### useEffect\r\n\r\n#### Quick summary\r\n\r\n- The `Effect` Hook lets you perform side effects in functional components\r\n- It is a close replacement for `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount`\r\n\r\nTo understand better, see the example below or interact with the code forking the project\r\n\r\n```js\r\n// 1️⃣  Import the useEffect and useState Hooks\r\n// ⚠️  Remember that we are using React v17, so you don't need to import \"React\" anymore\r\nimport { useEffect, useState } from 'react';\r\n\r\nfunction UseStateExample() {\r\n  // 2️⃣  Declare a new a statement variable and its function\r\n  // The \"count\" will have a initial value: 0\r\n  const [count, setCount] = useState(0);\r\n  // 4️⃣  Declare useEffect Hook\r\n  // You can see that it's an arrow function that receives two parameters\r\n  useEffect(() =\u003e {\r\n    // Here we perform the side effects\r\n    // After following the 3rd step\r\n    // The website title will be updated when the \"count\" changes\r\n    document.title = `${count}`;\r\n    // ⚠️  You need to pass the \"count\" as a dependency\r\n    // Once the  \"count\" changes every time, we have a side-effect\r\n  }, [count])\r\n  \r\n  return (\r\n    \u003c\u003e\r\n      {/* 3️⃣  call the statement variable \"count\"\r\n          And its function to increase 1 on click\r\n      */}\r\n      \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003e\r\n        Count {count}\r\n      \u003c/button\u003e\r\n    \u003c/\u003e\r\n  )\r\n}\r\n```\r\n\r\n[More about useEffect Hook](https://reactjs.org/docs/hooks-effect.html)\r\n\r\n[🔝 Back to Top](#table-of-content)\r\n\r\n### useContext\r\n\r\n#### Quick summary\r\n\r\n- `Context` provides a way to pass data through the component tree without having to pass props down manually at every level\r\n\r\nTo understand better, see the example below or interact with the code forking the project\r\n\r\n```js\r\n// ⚠️  Remember that we are using React v17, so you don't need to import \"React\" anymore\r\n// 1️⃣  Import createContext and useContext Hooks\r\nimport { createContext, useContext } from 'react';\r\n// To explain better, we'll create a themed button\r\n// So, you'll have a light and dark themes\r\nconst themes = {\r\n  light: {\r\n    foreground \"#000\",\r\n    background: \"#eee\"\r\n  },\r\n  dark: {\r\n    foreground: \"#fff\",\r\n    background: \"222\"\r\n  }\r\n}\r\n```\r\n\r\n```js\r\n// 2️⃣  Create a \"context\" and set a theme\r\n// Here you'll use the createContext Hook\r\n// Hint: Change to the dark mode and see how it works\r\nconst ThemeContext = createContext(themes.light)\r\n\r\nfunction ThemedButton() {\r\n  // 3️⃣  Provide the theme context created to be consumed\r\n  // Here you'll use the useContext Hook\r\n  const theme = useContext(ThemeContext);\r\n\r\n  return (\r\n    \u003c\u003e\r\n      {/* 4️⃣  Now you can create a styled button with the created themes */}\r\n      \u003cbutton\r\n        style={{ \r\n          background: theme.background,\r\n          color: theme.foreground\r\n        }}\r\n      \u003e\r\n        Look at me!!\r\n      \u003c/button\u003e\r\n    \u003c/\u003e\r\n  )\r\n}\r\n```\r\n\r\n[More about useContext Hook](https://reactjs.org/docs/hooks-reference.html#usecontext)\r\n\r\n[🔝 Back to Top](#table-of-content)\r\n\r\n### useReducer\r\n\r\n#### Quick summary\r\n\r\n- `useReducer` is a Hook that is used for state management\r\n- It is an alternative to `useState`\r\n- `useReducer` is related to reducer functions\r\n\r\n#### useState vs useReducer\r\n\r\n| Scenario   |      useState      |  useReducer |\r\n|------------|--------------------|-------------|\r\n| Type of state |  Number, String, Boolean | Object or Array |\r\n| Number of state transitions | One or two | Too many |\r\n| Related state transitions? | No | Yes |\r\n| Business logic | No business logic | Complex business logic |\r\n| Local vs Global | Local | Global |\r\n\r\nTo understand better, see the example below or interact with the code forking the project\r\n\r\n```js\r\n// ⚠️  Remember that we are using React v17, so you don't need to import \"React\" anymore\r\n// 1️⃣  Import useReducer Hook\r\nimport { useReducer } from 'react';\r\n// 2️⃣  Define an initial state\r\n// In this case, we'll call \"count\"\r\n// The \"count\" will have an initial value: 0\r\nconst initialState = {\r\n  count: 0\r\n}\r\n// 3️⃣  Create a reducer function\r\n// Here there will be two arguments\r\n// The \"state\" and an \"action\"\r\nfunction reducer(state, action) {\r\n  switch (action.type) {\r\n    // Increase 1 to the \"count\"\r\n    case 'INCREMENT':\r\n      return {\r\n        count: state.count + 1\r\n      }\r\n    // Decrease 1 to the \"count\"\r\n    case 'DECREMENT':\r\n      return {\r\n        count: state.count - 1\r\n      }\r\n    // Return the default state\r\n    default:\r\n      return state\r\n  }\r\n}\r\n```\r\n\r\n```js\r\nfunction UseReducerExample() {\r\n  // 4️⃣  Access the statemente variable dispatch it\r\n  // Here you'll use useReducer Hook\r\n  // You see that we pass the reducer function and the initial state\r\n  // To a \"state\" and \"dispatch\"\r\n  const [state, dispatch] = useReducer(reducer, initialState);\r\n\r\n  return (\r\n    \u003c\u003e\r\n      {/* 5️⃣  Pass the statemente variable \"count\" \r\n          And its actions to increase and decrease\r\n      */}\r\n      \u003cp\u003eCount {state.count}\u003c/p\u003e\r\n      {/* On click, increment 1 \r\n          So, you see that the dispatch specify which action we want\r\n      */}\r\n      \u003cbutton onClick={() =\u003e dispatch({ type: \"INCREMENT\" })}\u003e\r\n        +\r\n      \u003c/button\u003e\r\n      \u003cbutton onClick={() =\u003e dispatch({ type: \"DECREMENT\" })}\u003e\r\n        -\r\n      \u003c/button\u003e\r\n    \u003c/\u003e\r\n  )\r\n}\r\n```\r\n\r\n[More about useReducer Hook](https://reactjs.org/docs/hooks-reference.html#usereducer)\r\n\r\n[🔝 Back to Top](#table-of-content)\r\n\r\n### useCallback\r\n\r\n#### Quick summary\r\n\r\n- `useCallback` is a Hook that will return a memoized version of the callback function that only changes if one of the dependencies has changed\r\n- It is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders\r\n\r\nTo understand better, see the example below or interact with the code forking the project\r\n\r\n```js\r\n// useCallback/Example/button.js\r\n// ⚠️  Remember that we are using React v17, so you don't need to import \"React\" anymore\r\n\r\n// \"handleClick\" will have the receive function, like in \"onClick\"\r\n// \"children\" will be the type: \"Increment age\" and \"Increment salary\"\r\nfunction Button({ handleClick, children }) {\r\n  console.log('Rendering button ', children);\r\n\r\n  return \u003cbutton onClick={hanldeClick}\u003e{children}\u003c/button\u003e\r\n}\r\n\r\n// 3️⃣  To prevent be the same event (onClick) be rendered\r\n// You'll use React.memo\r\nexport React.memo(Button);\r\n```\r\n\r\n```js\r\n// useCallback/Example/counter.js\r\n// ⚠️  Remember that we are using React v17, so you don't need to import \"React\" anymore\r\n\r\n// \"text\" is the type: \"age\" and \"salary\"\r\n// \"count\" is the counter for each type\r\nfunction Counter({ text, count }) {\r\n  console.log(`Rendering ${text}`);\r\n\r\n  return \u003c\u003e{text} {count}\u003c/\u003e\r\n}\r\n\r\n// 3️⃣  To prevent be the same event (onClick) render the same result\r\n// You'll use React.memo\r\nexport React.memo(Counter);\r\n```\r\n\r\n```js\r\n// ⚠️  Remember that we are using React v17, so you don't need to import \"React\" anymore\r\n// 1️⃣  Import useCallback and useState Hooks\r\nimport { useCallback, useState } from 'react';\r\n\r\nfunction UseCallbackExample() {\r\n  // 2️⃣  Declare a new a statement variable and its function\r\n  // The \"age\" have a initial value: 25\r\n  // And the \"salary\": 50000\r\n  const [age, setAge] = useState(25);\r\n  const [salary, setSalary] = useState(5000);\r\n  // 4️⃣  To prevent an event rendered (even if not clicked)\r\n  const incrementAge = useCallback(() =\u003e {\r\n    setAge(age + 1)\r\n  }, [age])\r\n  // 4️⃣  To prevent an event be rendered (even if not clicked)\r\n  const incrementSalary = useCallback(() =\u003e {\r\n    setSalary(salary + 1)\r\n  }, [salary])\r\n\r\n  return (\r\n    \u003c\u003e\r\n      \u003cCounter text=\"Age\" count={age} /\u003e\r\n      \u003cButton handleClick={incrementAge}\u003e\r\n        Increment age\r\n      \u003c/Button\u003e\r\n      \u003cCounter text=\"Salary\" count={salary} /\u003e\r\n      \u003cButton handleClick={incrementSalary}\u003e  \r\n        Increment salary\r\n      \u003c/Button\u003e\r\n    \u003c/\u003e\r\n  )\r\n}\r\n```\r\n\r\n[More about useCallback Hook](https://reactjs.org/docs/hooks-reference.html#usecallback)\r\n\r\n[🔝 Back to Top](#table-of-content)\r\n\r\n### useMemo\r\n\r\n```js\r\n// useMemo/Example/index.js\r\n// ⚠️  Remember that we are using React v17, so you don't need to import \"React\" anymore\r\n// 1️⃣  Import useMemo and useState Hooks\r\nimport { useMemo, useState } from 'react';\r\n\r\nfunction UseMemoExample() {\r\n  // 2️⃣  Declare a new a statement variable and its function\r\n  // Both \"counters\" will have a initial value: 0\r\n  const [counterOne, setCounterOne] = useState(0);\r\n  const [counterTwo, setCounterTwo] = useState(0);\r\n  // Increment 1 to the \"counterOne\"\r\n  const incrementOne = () =\u003e setCounterOne(counterOne + 1)\r\n  // Increment 1 to the \"counterTwo\" \r\n  const incrementTwo = () =\u003e setCounterTwo(counterTwo + 1)\r\n  // 4️⃣  To prevent an event be renderred unnecessarily¹\r\n  // You'll need to use useMemo Hook\r\n  const isEven = useMemo(() =\u003e {\r\n    let i = 0;\r\n    // Compute an expensive operation¹\r\n    while (i \u003c 2000000000) i++;\r\n    // Return \"Even\" numbers\r\n    return counterOne % 2 === 0;\r\n  }, [counterOne])\r\n\r\n  return (\r\n    \u003c\u003e\r\n      {/* 3️⃣  Call the statemente variable \"counterOne\" and \"counterTwo\" \r\n          Call the function to both \"counters\" and increment 1\r\n      */}\r\n      \u003cbutton onClick={incrementOne}\u003e\r\n        Counter One {counterOne}\r\n      \u003c/button\u003e\r\n      \u003cspan\u003e{isEven ? \"Even\" : \"Odd\"}\u003c/span\u003e\r\n      \u003cbutton onClick={incrementTwo}\u003e\r\n        Counter Two {counterTwo}\r\n      \u003c/button\u003e\r\n    \u003c/\u003e\r\n  )\r\n}\r\n```\r\n\r\n[More about useMemo Hook](https://reactjs.org/docs/hooks-reference.html#usememo)\r\n\r\n[🔝 Back to Top](#table-of-content)\r\n\r\n### useRef\r\n\r\nTo understand better, see the example below or interact with the code forking the project\r\n\r\n```js\r\n// ⚠️  Remember that we are using React v17, so you don't need to import \"React\" anymore\r\n// 1️⃣  Import useRef Hook\r\n\r\nfunction UseRefExample() {\r\n  // 2️⃣  Create a new reference variable\r\n  // That will be connected to the \"input\"\r\n  // And will have a initial value: null\r\n  const inputRef = useRef(null);\r\n  // On click, focus the input\r\n  const focusOnClick = () =\u003e {\r\n    // \"current\" points to the mounted text \"input\"\r\n    inputRef.current.focus();\r\n  }\r\n\r\n  return (\r\n    \u003c\u003e\r\n      {/* 3️⃣  Call the \"ref\" property with the reference variable \"inputRef\" \r\n          And call the function to render the event\r\n      */}\r\n      \u003cinput ref={inputRef} type=\"text\" /\u003e\r\n      \u003cbutton onClick={focusOnClick}\u003e\r\n        Focus the input\r\n      \u003c/button\u003e\r\n    \u003c/\u003e\r\n  )\r\n}\r\n```\r\n\r\n[More about useRef Hook](https://reactjs.org/docs/hooks-reference.html#useref)\r\n\r\n[🔝 Back to Top](#table-of-content)\r\n\r\n### Custom Hooks\r\n\r\n#### Quick summary\r\n\r\n- A custom Hook is basically a JavaScript function whose name starts with `use`\r\n- A custom Hook can also call other Hooks if required\r\n- Share logic → Alternative to HOCs and Render Props\r\n\r\nTo understand better, see the example below or interact with the code forking the project\r\n\r\n```js\r\n// hooks/useInput.js\r\n// 1️⃣  Import useState Hook\r\n\r\nfunction useInput(initialValue) {\r\n  // 2️⃣  Declare a new a statement variable and its function\r\n  // \"value\" will have a initial state: \"initialValue\"\r\n  const [value, setValue] = useState(initialValue);\r\n  // Reset the input values when submit (onSubmit)\r\n  const reset = () =\u003e setValue(initialValue)\r\n  // Get the \"value\" and, onChange (when the user types), update it\r\n  const bind = {\r\n    value,\r\n    onChange: e =\u003e setValue(e.target.value)\r\n  }\r\n  // 3️⃣  To return and use the created functions in any component\r\n  // You'll need to use arrow destructuring\r\n  return [value, bind, reset];\r\n}\r\n\r\nexport default useInput;\r\n```\r\n\r\n```js\r\n// customHooks/Example3/useInput.js\r\n// ⚠️  Remember that we are using React v17, so you don't need to import \"React\" anymore\r\n// 1️⃣  Import useInput custom Hook\r\nimport useInput from '../../../hooks/useInput';\r\n\r\nfunction CustomHooksExample() {\r\n  // 4️⃣  Using arrows destructuring, create a new statement variable\r\n  // Besides that, we have to \"bind\" and \"reset\"\r\n  // So create for each statemente variable\r\n  const [firstName, bindFirstName, resetFirstName] = useInput('');\r\n  const [lastName, bindLastName, resetLastName] = useInput('');\r\n  // Alert the \"first name\" and \"last name\" when the user submits (onSubmit)\r\n  // And reset it (onSubmit)\r\n  const handleSubmit = e =\u003e {\r\n    e.preventDefault();\r\n\r\n    alert(`Hello, ${firstName} ${lastName}`);\r\n\r\n    resetFirstName();\r\n    resetLastName();\r\n  }\r\n\r\n  return (\r\n    \u003c\u003e\r\n      \u003cform onSubmit={handleSubmit}\u003e\r\n        {/* 5️⃣  As you've seen in the useInput custom Hook,\r\n            The \"value\" and \"onChange\" are used there.\r\n            So, you just need to \"bind\" everything (...)\r\n         */}\r\n        \u003cinput type=\"text\" {...bindFirstName} /\u003e\r\n        \u003cinput type=\"text\" {...bindLastName} /\u003e\r\n        \u003cbutton\u003eSubmit\u003c/button\u003e\r\n      \u003c/form\u003e\r\n    \u003c/\u003e\r\n  )\r\n}\r\n```\r\n\r\n[More about Custom Hooks](https://reactjs.org/docs/hooks-custom.html)\r\n\r\n[🔝 Back to Top](#table-of-content)\r\n\r\n---\r\n\r\nTo see more, access the [ReactJS oficial website](https://reactjs.org) or see the [React Hooks Playlist](https://www.youtube.com/playlist?list=PLC3y8-rFHvwisvxhZ135pogtX7_Oe3Q3A)\r\n\r\n---\r\n\r\n[LICENSE](./LICENSE)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesau-morais%2Freact-hooks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fesau-morais%2Freact-hooks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesau-morais%2Freact-hooks/lists"}