React
Hooks
Desenvolvimento
JavaScript
React19

Exploring React Hooks and React 19 Innovations

Exploring React Hooks and React 19 Innovations

Hooks revolutionized React development by allowing functional components to elegantly manage state, side effects, and complex logic. With React 19, new hooks were introduced to further streamline the workflow. In this article, we will explore classic hooks, advanced hooks, and what's new in version 19 with practical examples.


Basic React Hooks

useState: Simple State Management

Manages local states in functional components. Ideal for values ​​that change over time.

Example: Interactive Counter

import { useState } from 'react';

function Counter() { const [count, setCount] = useState(0);

return (

You clicked {count} times

<button onClick={() => setCount(count + 1)}> Increment
); }


useEffect: Side Effects

Executes code after rendering, such as API calls or DOM manipulation.

Example: Fetching Data from an API

import { useState, useEffect } from 'react';

function UserList() { const [users, setUsers] = useState([]);

useEffect(() => { fetch('https://api.example.com/users') .then(response => response.json()) .then(data => setUsers(data)); }, []); // Execute only once

return (

    {users.map(user => (
  • {user.name}
  • ))}
); }


useContext: Global State Sharing

Accesses context values without prop drilling.

Example: Dark/Light Theme

import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext();

function App() { const [theme, setTheme] = useState('light');

return ( <ThemeContext.Provider value=> </ThemeContext.Provider> ); }

function Toolbar() { const { theme, setTheme } = useContext(ThemeContext);

return ( <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}> Switch to theme {theme === 'light' ? 'dark' : 'light'} ); }


useRef: Mutable References

Stores values that persist between renders without causing re-renders.

Example: Focus on Input

import { useRef } from 'react';

function TextInput() { const inputRef = useRef(null);

const focusInput = () => { inputRef.current.focus(); };

return (

); }


Advanced and Customized Hooks

useReducer: Complex State

Manages states with more elaborate logic, similar to Redux.

Example: Task List

import { useReducer } from 'react';

function todosReducer(state, action) { switch (action.type) { case 'ADD_TODO': return [...state, { text: action.text, completed: false }]; case 'TOGGLE_TODO': return state.map((todo, index) => index === action.index ? { ...todo, completed: !todo.completed } : todo ); default: return state; } }

function TodoApp() { const [todos, dispatch] = useReducer(todosReducer, []);

const handleSubmit = (e) => { e.preventDefault(); dispatch({ type: 'ADD_TODO', text: e.target.elements.todo.value }); e.target.reset(); };

return (

{todos.map((todo, index) => ( < key={index} onClick={() => dispatch({ type: 'TOGGLE_TODO', index })} style={ textDecoration: todo.completed ? 'line-through' : 'none' } > {todo.text}
))} ); }


useMemo and useCallback: Performance Optimization

  • useMemo: Memorizes calculated values.
  • useCallback: Memorizes functions.

Example: Heavy Calculation

import { useMemo, useState } from 'react';

function ExpensiveComponent({ list }) { const sortedList = useMemo(() => { console.log('Ordering list...'); return [...list].sort(); }, [list]);

return

{sortedList.join(', ')}
; }


Custom Hooks: Logic Reuse

Example: useFetch for HTTP Requests

import { useState, useEffect } from 'react';

function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true);

useEffect(() => { fetch(url) .then(res => res.json()) .then(data => { setData(date); setLoading(false); }); }, [url]);

return { data, loading }; }

// Usage in the component: function UserProfile({ userId }) { const { data: user, loading } = useFetch(https://api.example.com/users/${userId});

if (loading) return

Loading...
; return
{user.name}
; }


New React 19 Hooks

useOptimistic: Optimistic Updates

Updates UI before server commit, rolling back in case of failure.

Example: Optimistic Comment Addition

import { useOptimistic } from 'react';

function CommentForm({ onSubmit }) { const [optimisticComments, addOptimisticComment] = useOptimistic( [], (state, newComment) => [...state, { text: newComment, sending: true }] );

const handleSubmit = async (e) => { e.preventDefault(); const formData = new FormData(e.target); const comment = formData.get('comment');

addOptimisticComment(comment);

try {
  await onSubmit(comment);
} catch (error) {
  // Revert the UI if the request fails
}

};

return (

{optimisticComments.map((comment, index) => ( <div style=> {comment.text}
))} ); }


useResource: Integration with Suspense

Manages asynchronous data declaratively.

Example: Data Loading with Fallback

import { useResource, Suspense } from 'react';

function fetchUser(id) { // Returns a promise }

function UserProfile({ userId }) { const userResource = useResource(() => fetchUser(userId));

return

{userResource.read().name}
; }

// Usage in the parent component: <Suspense fallback={

Loading user...
}>


useEventListener: Simplified Event Listeners

Manages event listeners cleanly.

Example: Monitor Window Size

import { useEventListener } from 'react';

function WindowSize() { const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });

useEventListener('resize', () => { setSize({ width: window.innerWidth, height: window.innerHeight }); });

return

Window size: {size.width}x{size.height}
; }


useMediaQuery: Responsive Design

Reacts to changes in media queries.

Example: Dark Theme with System Preference

import { useMediaQuery } from 'react';

function DarkModeToggle() { const prefersDark = useMediaQuery('(prefers-color-scheme: dark)'); const [isDark, setIsDark] = useState(prefersDark);

// Update the site theme here...

return ( <button onClick={() => setIsDark(!isDark)}> {isDark? 'Disable dark mode' : 'Enable dark mode'} ); }


useErrorBoundary: Elegant Error Handling

Catches errors in child components.

Example: Custom Error Threshold

import { useErrorBoundary } from 'react';

function ErrorProneComponent() { const { ErrorBoundary, didCatch, error } = useErrorBoundary();

return didCatch ? (

An error occurred: {error.message}
) : ( ); }


Conclusion

React hooks continue to evolve, bringing powerful tools to simplify development. With React 19, features like useOptimistic and useResource elevate the user experience by handling asynchronous operations fluidly, while hooks like useMediaQuery and useEventListener make it easier to create adaptive interfaces.

By mastering these hooks, from the basics to the latest, you will be equipped to build more robust, performant and easier to maintain applications. Try integrating these techniques into your projects and see how they transform your workflow! 🚀

Also read