0% found this document useful (0 votes)
23 views

React Native Hooks

The document provides a comprehensive overview of React Native hooks, detailing their availability in both ReactJS and React Native. It categorizes hooks into state management, effect, ref, performance, context, transition, random utility, custom, and React Native specific hooks, highlighting which are exclusive to each environment. Additionally, it includes practical examples and best practices for using these hooks effectively in React Native applications.

Uploaded by

shreyas
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views

React Native Hooks

The document provides a comprehensive overview of React Native hooks, detailing their availability in both ReactJS and React Native. It categorizes hooks into state management, effect, ref, performance, context, transition, random utility, custom, and React Native specific hooks, highlighting which are exclusive to each environment. Additionally, it includes practical examples and best practices for using these hooks effectively in React Native applications.

Uploaded by

shreyas
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

React Native hooks

Here’s a table summarizing React Hooks and their availability in ReactJS and
React Native:

Present (✓) / Not


React Hook ReactJS React Native
Present (✘)

State Management
Hooks

🛠️ useState ✓ ✓ Present

🛠️ useReducer ✓ ✓ Present

🛠️
useSyncExternalStore
✓ ✘ ReactJS only

Effect Hooks

⚡ useEffect ✓ ✓ Present

⚡ useLayoutEffect ✓ ✓ Present

⚡ useInsertionEffect ✓ ✘ ReactJS only

Ref Hooks

🪝 useRef ✓ ✓ Present

🪝 useImperativeHandle ✓ ✓ Present

Performance Hooks

⏩ useMemo ✓ ✓ Present

⏩ useCallback ✓ ✓ Present

Context Hooks

🌍 useContext ✓ ✓ Present

Transition Hooks

🚦 useTransition ✓ ✓ Present

🚦 useDeferredValue ✓ ✓ Present

Random Utility Hooks

🎲 useDebugValue ✓ ✓ Present

🎲 useId ✓ ✘ ReactJS only

Custom Hooks

React Native hooks 1


🔧 Custom Hooks ✓ ✓ Present

React Native Specific


Hooks

🧭 useWindowDimensions ✘ ✓ React Native only

🌒 useColorScheme ✘ ✓ React Native only

🎮useDeviceOrientation
✘ ✓ React Native only

🌐 useNetInfo ✘ ✓ React Native only

🦽 useBackHandler ✘ ✓ React Native only

📲 useSafeAreaInsets ✘ ✓ React Native only

⌨️ useKeyboard ✘ ✓ React Native only

⚙️ useFocusEffect ✘ ✓
React Native only (with
React Navigation)

Summary:
Present in both ReactJS and React Native: useState , useEffect , useReducer ,
useRef , useMemo , useCallback , useContext , useTransition , useDeferredValue ,
useDebugValue , useImperativeHandle , and Custom Hooks.

Present only in ReactJS: useSyncExternalStore , useInsertionEffect , and useId .

Present only in React Native: useWindowDimensions , useColorScheme ,


useDeviceOrientation , useNetInfo , useBackHandler , useSafeAreaInsets , useKeyboard ,
and useFocusEffect .

This table should give you a clear idea of which hooks are available in each
environment!

1. 🛠️ useState in React Native


useStateis used in React Native just like in React. It allows you to manage state
within functional components, often used for UI elements, handling input
values, and toggling visibility.

React Native hooks 2


How It Works:
Initialize state with an initial value.

Returns an array: the current state and a function to update it.

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

React Native Specific Examples:


1. Form Inputs:
Capture user input in forms.

const [name, setName] = useState('');


<TextInput
value={name}
onChangeText={setName}
placeholder="Enter your name"
/>

2. Toggling UI Components:
Show/hide components based on state.

const [isModalOpen, setModalOpen] = useState(false);


<Modal visible={isModalOpen} />
<Button title="Open Modal" onPress={() => setModalOpen(t
rue)} />

3. Counter Logic:
Manage a simple counter with button presses.

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


<Button title="Increment" onPress={() => setCount(count
+ 1)} />

2. 🛠️ useReducer in React Native

React Native hooks 3


useReducer is an alternative to useState for managing more complex state logic,
useful when handling multiple interdependent states, especially in large forms
or complex apps like games or shopping carts.

How It Works:
Accepts two arguments: the reducer function and the initial state.

Returns an array: the current state and a dispatch function to update it.

const [state, dispatch] = useReducer(reducer, initialStat


e);

React Native Specific Examples:


1. Complex State Dependencies:
Manage multiple state values, such as a form with different inputs.

const reducer = (state, action) => {


switch (action.type) {
case 'update_name':
return { ...state, name: action.payload };
case 'update_age':
return { ...state, age: action.payload };
default:
return state;
}
};
const [state, dispatch] = useReducer(reducer, { name:
'', age: '' });

// Using TextInput
<TextInput value={state.name} onChangeText={text => disp
atch({ type: 'update_name', payload: text })} />

2. Game State Management:


Track states like score, level, etc., in a game app.

React Native hooks 4


const reducer = (state, action) => {
switch (action.type) {
case 'increment_score':
return { ...state, score: state.score + action.pay
load };
default:
return state;
}
};
const [state, dispatch] = useReducer(reducer, { score: 0
});
<Button title="Increase Score" onPress={() => dispatch({
type: 'increment_score', payload: 10 })} />

3. Shopping Cart:
Add or remove items in a shopping cart.

const reducer = (cart, action) => {


switch (action.type) {
case 'add_item':
return [...cart, action.payload];
case 'remove_item':
return cart.filter(item => item.id !== action.payl
oad.id);
default:
return cart;
}
};
const [cart, dispatch] = useReducer(reducer, []);

Where useReducer Is Helpful in React Native:


When managing complex or multiple interrelated states, such as forms with
many fields.

When state transitions depend on user interactions or other states.

Ideal for apps with complex state, like e-commerce apps or games.

React Native hooks 5


Both hooks, useState and useReducer , are essential tools in React Native for
handling state in functional components, helping build dynamic and interactive
mobile apps.

1. ⚡ useEffect in React Native


In React Native, useEffect is used to handle side effects such as fetching data,
subscribing to events, or updating state based on props, just like in React. It
runs asynchronously after the render phase, allowing your app to interact with
the UI.

How It Works:
Accepts two arguments:

1. A callback function that contains your side effect logic.

2. An optional dependency array that controls when the effect runs.

useEffect(() => {
console.log("Effect ran!");
}, [dependency]);

React Native Specific Examples:


1. Data Fetching:

Fetch data when the component is mounted or when a dependency


changes.

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

React Native hooks 6


2. Subscribing to Events:

Subscribe to events such as device orientation changes or keyboard


visibility.

useEffect(() => {
const handleOrientationChange = (event) => console.l
og(event);
Dimensions.addEventListener('change', handleOrientat
ionChange);
return () => Dimensions.removeEventListener('chang
e', handleOrientationChange);
}, []);

3. Updating State Based on Props:

Perform state changes when props change.

useEffect(() => {
setDerivedState(props.value * 2);
}, [props.value]);

Where It’s Helpful in React Native:


For asynchronous operations like fetching data or listening to events.

When side effects depend on state or props.

Best for effects that don’t block rendering and can run after the UI update.

2. ⚡ useLayoutEffect in React Native


works similarly to useEffect , but it fires synchronously after all
useLayoutEffect

the DOM mutations and before the UI is painted. In React Native, this is useful
when you need to perform layout adjustments or measure dimensions before
rendering.

How It Works:
Syntax and arguments are the same as useEffect .

Runs immediately after layout changes, blocking rendering until the effect is
complete.

React Native hooks 7


useLayoutEffect(() => {
console.log("Layout Effect ran!");
}, [dependency]);

React Native Specific Examples:


1. Measuring Layouts:

Capture the dimensions of a component before rendering it on the screen.

const elementRef = useRef();

useLayoutEffect(() => {
const dimensions = elementRef.current?.getBoundingCl
ientRect();
console.log(dimensions);
}, []);

2. Synchronizing Scrolling:
You can scroll to a specific position after layout changes, such as scrolling
to the top of a list after data is updated.

useLayoutEffect(() => {
scrollViewRef.current?.scrollTo({ x: 0, y: scrollPos
ition, animated: true });
}, [scrollPosition]);

3. Animating Layout Changes:


Use layout effects for smooth animations that need to run after layout
changes.

const elementRef = useRef();

useLayoutEffect(() => {
elementRef.current?.setNativeProps({
style: { transform: [{ scale: 1.2 }] }

React Native hooks 8


});
}, []);

Where It’s Helpful in React Native:


When you need to measure or manipulate the layout immediately after
render but before the UI is visible.

Ideal for tasks that should happen synchronously, such as animations or


layout calculations.

Avoid using for expensive operations, as it can block rendering.

Both useEffect and useLayoutEffect help with handling side effects in React
Native, with useLayoutEffect providing a way to ensure changes are applied
immediately after the layout update, which is especially useful for animations
and layout measurements.

1. ⏩ useMemo in React Native


In React Native, useMemo is used to memoize computed values or results of
functions to prevent unnecessary recalculations when dependencies have not
changed. This is especially useful for preventing expensive computations on
each render.

How It Works:
Accepts a function that returns a value and a dependency array. The
function is re-evaluated only when a dependency changes.

const memoizedValue = useMemo(() => computeExpensiveValue


(a, b), [a, b]);

React Native Specific Examples:


1. Expensive Calculations:

React Native hooks 9


Avoid redundant computations on each render.

function ExpensiveComponent({ a, b }) {
const computedValue = useMemo(() => {
console.log("Computing...");
return a + b; // Expensive computation
}, [a, b]);

return <Text>Computed Value: {computedValue}</Text>;


}

2. Derived State:
Memoize derived state based on props or state changes.

function FilteredList({ items, filter }) {


const filteredItems = useMemo(() => {
return items.filter((item) => item.includes(filt
er));
}, [items, filter]);

return (
<FlatList
data={filteredItems}
keyExtractor={(item) => item}
renderItem={({ item }) => <Text>{item}</Text
>}
/>
);
}

3. Preventing Re-renders with Pure Components:


Use useMemo to pass memoized values to child components.

const memoizedOptions = useMemo(() => generateOptions(),


[data]);

return <Dropdown options={memoizedOptions} />;

React Native hooks 10


Where It’s Helpful in React Native:
When rendering lists, filtering, or running heavy computations that don’t
need to execute on every render.

Helps optimize components with derived data.

2. ⏩ useCallback in React Native


useCallback is used to memoize functions, ensuring the same instance of the
function is used unless its dependencies change. This is useful for preventing
unnecessary re-creation of functions and re-renders of child components.

How It Works:
Accepts a function and a dependency array. Returns the same function
reference unless dependencies change.

const memoizedCallback = useCallback(() => {


doSomething(a, b);
}, [a, b]);

React Native Specific Examples:


1. Passing Stable Callbacks to Children:
Prevent unnecessary re-renders of child components that rely on stable
references.

const Child = React.memo(({ onClick }) => {


console.log("Child re-rendered");
return <Button onPress={onClick} title="Click Me" /
>;
});

function Parent() {
const [count, setCount] = React.useState(0);

const handleClick = useCallback(() => {


console.log("Button clicked");
}, []);

React Native hooks 11


return (
<>
<Text>Count: {count}</Text>
<Button onPress={() => setCount(count + 1)}
title="Increment" />
<Child onClick={handleClick} />
</>
);
}

2. Event Handlers with Stable References:


Avoid re-creating event handlers on every render.

function Button({ onPress }) {


return <Button onPress={onPress} title="Click Me" /
>;
}

function App() {
const [count, setCount] = React.useState(0);

const increment = useCallback(() => {


setCount((prev) => prev + 1);
}, []);

return <Button onPress={increment} />;


}

3. Performance Optimization in Lists:

Optimize list rendering with event handlers.

function List({ items }) {


const handleClick = useCallback((item) => {
console.log(item);
}, []);

return (

React Native hooks 12


<FlatList
data={items}
keyExtractor={(item) => item}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => handleC
lick(item)}>
<Text>{item}</Text>
</TouchableOpacity>
)}
/>
);
}

Where It’s Helpful in React Native:


When passing functions to memoized child components to prevent
unnecessary re-renders.

Reduces function re-creation in performance-critical applications.

Comparison of useMemo and useCallback

Aspect useMemo useCallback

Purpose Memoize a value or computation. Memoize a function.

Primary Use Prevent recalculations of Avoid re-creation of stable


Case expensive operations. callbacks.

Event handlers, passing


Common Usage Filtering, sorting, deriving state.
callbacks to children.

Best Practices for Performance Hooks


1. Avoid Premature Optimization:

Use useMemo and useCallback only when performance bottlenecks are


evident. Overuse can lead to unnecessary complexity.

2. Keep Dependency Arrays Accurate:

Always include all dependencies in the array to avoid bugs.

3. When to Use:

React Native hooks 13


Use useMemo for heavy computations or derived state.

Use useCallback for memoized event handlers or to pass stable


references to child components.

By applying these hooks judiciously in your React Native applications, you can
improve their performance and maintainability, even in complex scenarios with
heavy computations or event handling.

Context Hooks in React Native


useContext in React Native functions similarly to how it works in React for web. It
allows you to access and share global data across your component tree without
having to manually pass props at every level. It is particularly useful for shared
state like authentication status, theme preferences, and more.

🌍 useContext

How It Works:
1. Create a Context using React.createContext .

2. Wrap your component tree with a Provider and pass a value to it.

3. Consume the context value inside any child component using useContext .

Syntax:

const MyContext = React.createContext(defaultValue);

// Providing Context
<MyContext.Provider value={providedValue}>
<ChildComponent />
</MyContext.Provider>

// Consuming Context
const value = useContext(MyContext);

Key Features of useContext :


Simplifies state and data sharing across components.

React Native hooks 14


Eliminates "prop drilling" (passing props through layers of intermediary
components).

Use Cases for useContext in React Native:

1. Global State Management


For shared state like user authentication, theme settings, or app settings.
Example:

const AuthContext = React.createContext();

function App() {
const [isAuthenticated, setAuthenticated] = React.useSt
ate(false);

return (
<AuthContext.Provider value={{ isAuthenticated, set
Authenticated }}>
<Login />
<Dashboard />
</AuthContext.Provider>
);
}

function Login() {
const { setAuthenticated } = useContext(AuthContext);
return <Button onPress={() => setAuthenticated(true)} t
itle="Login" />;
}

function Dashboard() {
const { isAuthenticated } = useContext(AuthContext);
return <Text>{isAuthenticated ? "Welcome!" : "Please lo
g in."}</Text>;
}

React Native hooks 15


2. Theme Switching
Managing and switching between light/dark themes.

Example:

const ThemeContext = React.createContext();

function App() {
const [theme, setTheme] = React.useState("light");

return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<Header />
<Main />
</ThemeContext.Provider>
);
}

function Header() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<Header>
<Button onPress={() => setTheme(theme === "ligh
t" ? "dark" : "light")}>
Switch to {theme === "light" ? "dark" : "li
ght"} mode
</Button>
</Header>
);
}

function Main() {
const { theme } = useContext(ThemeContext);
return <View style={{ backgroundColor: theme === "ligh
t" ? "#fff" : "#333" }}><Text>Current theme: {theme}</Text>
</View>;
}

React Native hooks 16


3. Localization
Managing multiple languages for an app’s content.

Example:

const LanguageContext = React.createContext();

function App() {
const [language, setLanguage] = React.useState("en");

return (
<LanguageContext.Provider value={{ language, setLan
guage }}>
<LanguageSwitcher />
<Content />
</LanguageContext.Provider>
);
}

function LanguageSwitcher() {
const { language, setLanguage } = useContext(LanguageCo
ntext);
return (
<Button onPress={() => setLanguage(language === "e
n" ? "es" : "en")}>
Switch to {language === "en" ? "Spanish" : "Eng
lish"}
</Button>
);
}

function Content() {
const { language } = useContext(LanguageContext);
return <Text>{language === "en" ? "Hello" : "Hola"}</Te
xt>;
}

4. Avoiding Prop Drilling

React Native hooks 17


useContext avoids passing props through many levels of components, which is
useful when deeply nested components need shared data.
Example:

const UserContext = React.createContext();

function App() {
return (
<UserContext.Provider value="John Doe">
<Grandparent />
</UserContext.Provider>
);
}

function Grandparent() {
return <Parent />;
}

function Parent() {
return <Child />;
}

function Child() {
const userName = useContext(UserContext);
return <Text>User: {userName}</Text>;
}

5. Integration with Third-Party Libraries


Libraries like Redux, Zustand, and Apollo Client use useContext under the hood
to provide state or data to components. This allows for easy integration of
global state management in React Native.

Where useContext Is Helpful in React Native:


1. Global Data Sharing:

Ideal for global settings that are accessed by multiple components. For
example, user authentication status or themes.

React Native hooks 18


2. Cross-Component Communication:

Useful when sibling or distant components need access to shared data


without manually passing props.

3. Avoiding Prop Drilling:

Helps eliminate the need to pass props through multiple levels of


intermediary components.

4. Application Configuration:

Store and access global settings such as API endpoints, feature toggles,
etc.

5. Multi-Layered Nested Components:

Provides direct access to data in deeply nested components without


intermediary layers.

Best Practices for useContext in React Native:


1. Avoid Overusing Context:

Use useContext for global state that does not change frequently. For
high-frequency updates (like real-time inputs), state management
libraries like Redux are more suitable.

2. Split Contexts for Large Apps:

Use separate contexts for different concerns (e.g., separate contexts


for auth, theme, and localization) to keep your app modular and
organized.

3. Keep Context Values Stable:

Memoize context values using useMemo to avoid unnecessary re-renders


of components that consume the context.

const value = React.useMemo(() => ({ state, dispatch }),


[state, dispatch]);
<Context.Provider value={value}>{children}</Context.Prov
ider>

4. Debugging:

React Native hooks 19


Use React Developer Tools to inspect context values and debug their
propagation through the component tree.

By using useContext wisely, you can manage global data, prevent prop drilling,
and build clean, maintainable React Native applications.

Random Utility Hooks in React (Modified for React Native)


React Native shares many concepts with React, but there are some differences.
The following utility hooks and concepts, such as useDebugValue , can be useful
for debugging, improving accessibility, and managing data, but keep in mind
that some hooks like useId are not available in React Native.

Let’s dive into how these might work for React Native.

🎲 useDebugValue Hook (React Native Context)

What It Is:
useDebugValue is a hook primarily designed for debugging custom hooks in
development. It helps you display debug information in the React DevTools for
custom hooks, making it easier to inspect the internal state of hooks during
development. Although React Native does not have full support for useDebugValue

in all scenarios, you can still use it in certain situations for debugging.

How It Works:
takes an argument (typically a value or state) and displays it in the
useDebugValue

React DevTools. This helps when you're creating custom hooks that involve
complex logic, enabling you to monitor the state or output in real-time.

Basic Syntax (same as React):

useDebugValue(value)

: The value to display in DevTools, such as a primitive, object, or


value

function.

Example Usage for React Native:

React Native hooks 20


Let’s say you're building a custom hook to fetch data from an API. You can use
useDebugValue to log the loading status or the result of the API call.

import { useState, useEffect, useDebugValue } from "react";

function useFetchData(url) {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
async function fetchData() {
const response = await fetch(url);
const result = await response.json();
setData(result);
setIsLoading(false);
}

fetchData();
}, [url]);

// Display debug info in React DevTools


useDebugValue(isLoading ? "Loading..." : "Data Loade
d");

return { data, isLoading };


}

function App() {
const { data, isLoading } = useFetchData("https://jsonp
laceholder.typicode.com/posts");

if (isLoading) {
return <Text>Loading...</Text>;
}

return <Text>{data && data[0].title}</Text>;


}

React Native hooks 21


Here:

useFetchData is a custom hook to fetch data from an API and return the data
with a loading state.

useDebugValue is used to log the isLoading state. If data is loading, you will
see "Loading..." in the DevTools, and once loaded, it will show "Data Loaded" .

When to Use useDebugValue :


Debugging Custom Hooks: Useful when creating complex custom hooks
and needing insights into internal states.

Monitoring Hook State: Helps keep track of critical state within custom
hooks in React Native during development.

Improving Developer Experience: Provides deeper visibility into hooks'


behavior for better debugging.

When Not to Use useDebugValue :


Production Builds: Avoid using this hook in production code as it is
primarily for development and doesn't affect app performance, but doesn't
add value in production.

Regarding useId :
As of now, React Native does not support the useId hook available in React.
This hook is used in React to generate stable unique IDs, which is helpful in
scenarios like form inputs or accessibility purposes where IDs are required for
labeling or references.
Alternative for React Native:
If you need unique IDs for accessibility or other purposes, you can use
JavaScript methods like
Math.random() or libraries like uuid to generate unique IDs manually. For

example:

import { TextInput } from 'react-native';


import { v4 as uuidv4 } from 'uuid';

const MyComponent = () => {


const id = uuidv4(); // Unique ID for each instance

React Native hooks 22


return <TextInput accessibilityLabel={`Input field ${id}
`} />;
};

This provides a way to handle unique IDs in React Native while awaiting any
future updates from the React Native ecosystem.

By understanding these differences and applying similar techniques, you can


improve your debugging process and handle unique data efficiently in React
Native applications.

Custom Hooks in React (Modified for React Native)


Custom Hooks are a powerful feature in React that allows you to extract
reusable logic into functions that can be shared across different components.
React Native supports custom hooks in the same way as React, allowing you to
encapsulate reusable logic like fetching data, form handling, and tracking
window size, while keeping your codebase clean and maintainable.

What Is a Custom Hook?


A Custom Hook in React or React Native is a JavaScript function that:

Uses built-in hooks: It can use hooks like useState , useEffect , useContext ,
and others inside it.

Returns values or functions: Just like built-in hooks, it can return values or
functions that are needed by the components.

Encapsulates reusable logic: It organizes the logic into reusable units that
help in separating concerns.

Custom Hook Example (React Native):

import { useState, useEffect } from 'react';


import { Dimensions } from 'react-native';

function useWindowWidth() {
const [width, setWidth] = useState(Dimensions.get('windo
w').width);

React Native hooks 23


useEffect(() => {
const handleResize = () => setWidth(Dimensions.get('win
dow').width);

Dimensions.addEventListener('change', handleResize);

// Clean up on component unmount


return () => Dimensions.removeEventListener('change', h
andleResize);
}, []);

return width;
}

In this example:

useWindowWidth is a custom hook that tracks the window’s width using React
Native's Dimensions API.

It uses the useState and useEffect hooks internally.

This custom hook is reusable, so you can use it in multiple components to


get the window's width.

Why Use Custom Hooks in React Native?


1. Code Reusability:

Custom hooks allow you to extract reusable logic from components.


For example, if multiple components need to track the screen width or
fetch data from an API, you can encapsulate that logic in a custom
hook.

This reduces duplication and increases maintainability.

2. Separation of Concerns:

By moving complex logic (like data fetching or event listeners) into


custom hooks, components remain focused on rendering the UI, while
the hook handles the logic.

This makes the code more clean, organized, and easier to maintain.

React Native hooks 24


3. Encapsulation of State Logic:

Custom hooks help encapsulate state management and side effects,


keeping the component's UI code cleaner and more readable.

You don't need to add state or side effect logic inside every component,
just use the custom hook wherever needed.

4. Enhanced Testability:

Custom hooks are pure JavaScript functions, which means they can
be tested independently of React Native components.

This isolation makes it easier to write unit tests for the logic without the
need for UI components.

5. Complex Operations:

Custom hooks allow you to implement complex logic (e.g., form


handling, animations, or API calls) and separate this from the UI logic in
the components.

You can also compose multiple hooks together to create more


complex, yet reusable functionality.

Use Cases for Custom Hooks in React Native

1. Fetching Data
A very common use case for custom hooks is data fetching. In React Native,
this is especially useful for interacting with REST APIs or other external data
sources.

Example:

import { useState, useEffect } from 'react';

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

useEffect(() => {
const fetchData = async () => {

React Native hooks 25


try {
const response = await fetch(url);
const result = await response.json();
setData(result);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);

return { data, loading, error };


}

function App() {
const { data, loading, error } = useFetch('https://api.ex
ample.com/data');

if (loading) return <Text>Loading...</Text>;


if (error) return <Text>Error: {error.message}</Text>;

return <Text>{JSON.stringify(data)}</Text>;
}

Why It’s Useful:

You can reuse useFetch in different components to fetch data from various
endpoints.

It handles the common logic of fetching data and managing loading/error


states.

2. Form Handling
Custom hooks are also useful for form handling, which is common in React
Native apps, especially for login or registration forms.

Example:

React Native hooks 26


import { useState } from 'react';

function useForm(initialState) {
const [formData, setFormData] = useState(initialState);

const handleChange = (e) => {


const { name, value } = e.target;
setFormData((prev) => ({
...prev,
[name]: value,
}));
};

const resetForm = () => setFormData(initialState);

return [formData, handleChange, resetForm];


}

function SignUp() {
const [formData, handleChange, resetForm] = useForm({ use
rname: '', email: '' });

const handleSubmit = (e) => {


e.preventDefault();
console.log(formData);
resetForm();
};

return (
<View>
<TextInput
placeholder="Username"
name="username"
value={formData.username}
onChange={handleChange}
/>
<TextInput
placeholder="Email"

React Native hooks 27


name="email"
value={formData.email}
onChange={handleChange}
/>
<Button title="Submit" onPress={handleSubmit} />
</View>
);
}

Why It’s Useful:

useForm encapsulates form-related logic such as handling input changes,


resetting the form, and managing state.

It can be reused across multiple forms, reducing code duplication.

3. Window Resize Listener


When working with React Native apps, you may need to adjust the layout based
on screen size, especially for different device orientations or screen sizes.
Example:

import { useState, useEffect } from 'react';


import { Dimensions } from 'react-native';

function useWindowSize() {
const [size, setSize] = useState({
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
});

useEffect(() => {
const handleResize = () => {
setSize({ width: Dimensions.get('window').width, heig
ht: Dimensions.get('window').height });
};

Dimensions.addEventListener('change', handleResize);

return () => {

React Native hooks 28


Dimensions.removeEventListener('change', handleResiz
e);
};
}, []);

return size;
}

function App() {
const { width, height } = useWindowSize();

return (
<View>
<Text>Width: {width}, Height: {height}</Text>
</View>
);
}

Why It’s Useful:

The useWindowSize hook tracks the window dimensions (width and height)
and can be used to adjust UI layout accordingly.

It can be reused wherever you need to monitor the screen size.

When to Use Custom Hooks in React Native:


When you want to reuse functionality across different components.

When you need to keep a component’s code clean by extracting logic that
doesn’t relate directly to rendering.

When you have complex logic that should be decoupled from the
component itself.

When you need to manage side effects or state changes outside of the
component's UI logic.

When Not to Use Custom Hooks:


Overcomplicating simple components: If the logic is straightforward, using
custom hooks may unnecessarily add complexity.

React Native hooks 29


When functionality is not reusable: If the logic is relevant to only one
component and won’t be reused, it's better to keep it inside the component
itself.

Conclusion:
Custom Hooks in React Native are a powerful tool for organizing and reusing
logic across components. They help encapsulate complex logic, improve
maintainability, and keep components clean and focused on UI rendering.
Custom hooks allow for better code organization, testing, and scalability of
your React Native applications.

Can you provide detailed notes on [your topic here], explaining it step-by-step
and including colorful and relevant emojis to make it engaging? here⇒

React Native hooks 30

You might also like