# Custom Hooks

## Custom Hooks

By convention, custom hooks are kept in their own file which follows the naming convention `useName.js`.

{% tabs %}
{% tab title="useCounter.js" %}

```jsx
import {useState} from "react"

// Custom Hook
function useCounter(){
    
    // Initialize state
    const [count, setCount] = useState(0) 
    
    // Create any functions we need for modifying the state
    function increment(){
        setCount(prevCount => prevCount + 1)
    }
    
    // Return whatever we want another component to have access to (count, increment)   
    return [count, increment]
}

export default useCounter


```

{% endtab %}

{% tab title="App.js" %}

```jsx
import React, {useState} from "react"
import useCounter from "./useCounter"

function App(){
    // Using Custom hooks' property and method
    const [count, increment] = useCounter()
    return (
        <div>
            <h1>The count is {count}</h1>
            <button onClick={increment}>Add 1</button>
        </div>
    )    
}

export default App
```

{% endtab %}

{% tab title="index.js" %}

```jsx
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"

ReactDOM.render(<App />, document.getElementById("root"))
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
&#x20;Hooks perform the following functions:

* initialize state
* create any functions we need for modifying the state
* return whatever we want another component to have access to (e.g. count, increment)
  {% endhint %}

## Using Custom Hook Replacing Render Props

Custom Hook is a great way to achieve reusability in functional component.

{% tabs %}
{% tab title="useToggler.js" %}

```jsx
import {useState} from "react"

function useToggler(defaultOnValue = false) {
    // Create the state
    const [isToggledOn, setIsToggledOn] = useState(defaultOnValue)
    
    // Create a method for easily flipping the isToggledOn value
    function toggler(){
        setIsToggledOn(prevIsToggledOn => !prevIsToggledOn)
    }
    
    // Return whatever we want another component to have access to (isToggledOn, toggler)   
    return [isToggledOn, toggler]
}

export default useToggler
```

{% endtab %}

{% tab title="Menu.js" %}

```jsx
import React, {useState} from "react"
import useToggler from "./useToggler"

function Menu(props) {
    // Using custom hook (providing `true` defaultOnValue)
    const [isToggledOn, toggler] = useToggler(true)
    
    return (
        <div>
            <button onClick={toggler}>{isToggledOn ? "Hide" : "Show"} Menu </button>
            <nav style={{display: isToggledOn ? "block" : "none"}}>
                <h6>Signed in as Coder123</h6>
                <p><a>Your Profile</a></p>
                <p><a>Your Repositories</a></p>
                <p><a>Your Stars</a></p>
                <p><a>Your Gists</a></p>
            </nav>
        </div>
    ) 
}

export default Menu
```

{% endtab %}

{% tab title="Favorite.js" %}

```jsx
import React, {useState} from "react"
import useToggler from "./useToggler"

function Favorite(props) {
    // Using custom hook (without providing a defaultOnValue)
    const [isToggledOn, toggler] = useToggler()
    
    return (
        <div>
            <h3>Click heart to favorite</h3>
            <h1>
                <span 
                    onClick={toggler}
                >
                    {isToggledOn ? "❤️" : "♡"}
                </span>
            </h1>
        </div>    
    ) 
}

export default Favorite
```

{% endtab %}

{% tab title="App.js" %}

```jsx
import React from "react"
import Menu from "./Menu"
import Favorite from "./Favorite"

function App() {
    return (
        <div>
            <Menu />
            <hr />
            <Favorite />
        </div>
    )
}

export default App
```

{% endtab %}

{% tab title="index.js" %}

```jsx
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"

ReactDOM.render(<App />, document.getElementById("root"))

```

{% endtab %}
{% endtabs %}
