Unlocking the Power of Utility Functions and Custom Hooks in React
Tags: customhook, react, reusable, cleancode
Published: 2024-06-26 21:13:36

Diving into utility functions and custom hooks can transform your React projects, let's learn by watching some examples!

## 🛠 Utility functions

- Can be used outside of react component
- Provide reusability and reduce code length

```js
// utils.js
export const capitalizeWords = (str) => {
  if (!str) return "";

  return str.replace(/\b\w/g, (char) => char.toUpperCase());
};
```

```js
// App.js
import { capitalizeWords } from "./utils/capitalizeWords";

const App = () => {
  const title = "welcome to my website";
  const subTitle = "im the magical programmer";
  const description = "i have a magical refactor wand!";

  return (
    <div>
      <h1>{capitalizeWords(capitalizedTitle)}</h1>
      <h3>{capitalizeWords(subTitle)}</h3>
      <p>{capitalizeWords(description)}</p>
    </div>
  );
};

export default TitleComponent;
```

## 🪝 Custom Hooks without State

- Can only be used inside react components

```js
// useLogger.js
import { useEffect } from "react";

const useLogger = (message) => {
  useEffect(() => {
    console.log(message);
  }, [message]);
};

export default useLogger;
```

```js
// App.js
import React from "react";
import useLogger from "./hooks/useLogger";

const App = () => {
  useLogger("LoggerComponent has mounted.");

  return (
    <div>
      <p>Check your console to see the log messages.</p>
    </div>
  );
};

export default App;
```

## 📦 Custom Hooks with State

- State **WILL NOT** be shared between component that use the same custom hooks

```js
// useFetchData.js
import { useState, useEffect } from "react";

const useFetchData = (url) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        setLoading(true);
        const response = await fetch(url);
        const result = await response.json();
        setData(result);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [url]);

  return { data, loading, error };
};

export default useFetchData;
```

```js
// App.js
import useFetchData from "./hooks/useFetchData";

const App = () => {
  const { data, loading, error } = useFetchData("https://api.example.com/data");

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error}</p>;

  return (
    <div>
      <h1>Fetched Data</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
};

export default App;
```

## 🔄 Custom Hooks with Selector/Context

- Since we are using redux/context it will share the state between component that use the same hook
- When the redux state used by the custom hook change all the component that use the custom hook will re-render

```js
// useUser.js
import { useSelector } from "react-redux";

const useUser = () => {
  const user = useSelector((state) => state.user);
  const fullName = `${user.name} ${user.surname}`;

  return { ...user, fullName };
};

export default useUser;
```

```js
// App.js
import useUserProfile from "./hooks/useUserProfile";

const App = () => {
  const { fullName, email } = useUser();

  return (
    <div>
      <h1>User Profile</h1>
      <p>Full Name: {fullName}</p>
      <p>Email: {email}</p>
    </div>
  );
};

export default UserProfile;
```

## Conclusion

Utility functions and custom hooks can change your React development process for the better , making your code not just work better but also cleaner and more professional.

Thank you for reading this, i hope you enjoyed :D