useEffect React and TypeScript

RMAG news

React + Typescript

Using useEffect in a React component with TypeScript involves ensuring that your effect functions, dependencies, and cleanup functions are properly typed. Here’s how you can do this:

Basic Example

Here’s a simple example of using useEffect with TypeScript:

tsxCopy code
import React, { useEffect, useState } from react;

const MyComponent: React.FC = () => {
const [data, setData] = useState<string | null>(null);

useEffect(() => {
// Fetching data
fetch(https://api.example.com/data)
.then(response => response.json())
.then(data => setData(data));

// Cleanup (if necessary)
return () => {
console.log(Cleanup if necessary);
};
}, []); // Dependency array

return <div>Data: {data}</div>;
};

export default MyComponent;

Typing the State

When using state, you need to specify the type of the state variable. In the example above, useState<string | null> specifies that the state can be a string or null.

Example with Dependencies

If you have dependencies, you should also type them:

tsxCopy code
import React, { useEffect, useState } from react;

const MyComponent: React.FC = () => {
const [count, setCount] = useState<number>(0);

useEffect(() => {
document.title = `Count: ${count}`;
}, [count]); // Re-run the effect only if count changes

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};

export default MyComponent;

Cleanup Function

Here’s an example with a cleanup function, typically used for subscriptions or timers:

tsxCopy code
import React, { useEffect, useState } from react;

const TimerComponent: React.FC = () => {
const [seconds, setSeconds] = useState<number>(0);

useEffect(() => {
const interval = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);

return () => {
clearInterval(interval);
};
}, []); // Run once on mount and cleanup on unmount

return <div>Seconds: {seconds}</div>;
};

export default TimerComponent;

Fetching Data with TypeScript

For data fetching, you can define the type of the data you expect:

tsxCopy code
import React, { useEffect, useState } from react;

interface Data {
id: number;
name: string;
}

const FetchDataComponent: React.FC = () => {
const [data, setData] = useState<Data | null>(null);

useEffect(() => {
fetch(https://api.example.com/data)
.then(response => response.json())
.then((data: Data) => setData(data))
.catch(error => console.error(error));

return () => {
// Any necessary cleanup
};
}, []); // Empty dependency array ensures this runs once on mount

return <div>{data ? `Name: ${data.name}` : Loading…}</div>;
};

export default FetchDataComponent;

Handling Subscriptions

If you’re dealing with subscriptions, you can type the cleanup function appropriately:

tsxCopy code
import React, { useEffect, useState } from react;

const SubscriptionComponent: React.FC = () => {
const [message, setMessage] = useState<string>();

useEffect(() => {
const subscription = subscribeToMessages((newMessage: string) => {
setMessage(newMessage);
});

return () => {
subscription.unsubscribe();
};
}, []); // Empty array ensures the effect runs only once

return <div>Message: {message}</div>;
};

function subscribeToMessages(callback: (message: string) => void) {
// Dummy subscription function
const interval = setInterval(() => {
callback(New message received);
}, 1000);

return {
unsubscribe: () => clearInterval(interval),
};
}

export default SubscriptionComponent;

Summary

Type the state variables: Ensure that the state types are correctly defined.

Type the data: When fetching data, define the type of the data you expect to receive.

Type the cleanup function: Ensure that any cleanup functions are typed correctly.

By following these guidelines, you can effectively use useEffect in your TypeScript React components.