How to Safely Update React State
source link: https://blog.bitsrc.io/how-to-safely-update-react-state-daac9e79417
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
How to Safely Update React State
Why you can’t perform a React state update on an unmounted component
Photo by Markus Winkler on Unsplash
While developing your React application, have you encountered the following errors:
As it mentions, you can’t update React’s state in an unmounted component, which has the potential to cause memory leaks. This usually happens in the context of an asynchronous operation or in a subscriber.
For example, when you are waiting to request data and then update the React state, the corresponding component is unloaded. Or when you subscribe to a message source and update the state, it is not cleared in useEffect
.
The following is a simple example, please click the button repeatedly to switch the component to show and hide, you will find the error on the console later:
So how do we safely update React state? This can be done with the help of useRef
and useEffect
:
const mountedRef = useRef(false);
useEffect(() => {
mountedRef.current = true;
return () => {
mountedRef.current = false;
};
}, []);
// if (mountedRef.current) {
// Update your state
// }
useEffect
without dependencies can know if the current component is still mounted. Such logic can be reused by different components, so we can write a useMountedState
custom hook:
import { useCallback, useEffect, useRef } from 'react';
const useMountedState = () => {
const mountedRef = useRef(false);
const get = useCallback(() => mountedRef.current, []);
useEffect(() => {
mountedRef.current = true;
return () => {
mountedRef.current = false;
};
}, []);
return get;
};
export default useMountedState;
Then in the above example we can use it to solve the BUG:
const isMounted = useMountedState()
useEffect(() => {
sleep(1000).then(() => {
if (isMounted()) {
setText("Hi, SubComponent");
}
});
}, [isMounted]);
In most cases such a useMountedState
hook is sufficient, but if we go further, we can write a custom useSafeState
hook:
import { useCallback, useEffect, useState, useRef } from 'react';
import type { Dispatch, SetStateAction } from 'react';
function useSafeState<S>(
initialState: S | (() => S)
): [S, Dispatch<SetStateAction<S>>];
function useSafeState<S = undefined>(): [
S | undefined,
Dispatch<SetStateAction<S | undefined>>
];
function useSafeState<S>(initialState?: S | (() => S)) {
const mountedRef = useRef(false);
const [state, setState] = useState(initialState);
useEffect(() => {
mountedRef.current = true;
return () => {
mountedRef.current = false;
};
}, []);
const setCurrentState = useCallback((currentState: S) => {
if (mountedRef.current) {
setState(currentState);
}
}, []);
return [state, setCurrentState] as const;
}
export default useSafeState;
This brings another level of abstraction to our coding. Have fun!
Not a Medium member? Support me here by becoming one.
Build apps with reusable components like Lego
Bit’s open-source tool help 250,000+ devs to build apps with components.
Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.
Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:
→ Micro-Frontends
→ Design System
→ Code-Sharing and reuse
→ Monorepo
Recommend
-
44
Wrangling Untrusted File Formats Safely ( Formerly known as Puffs : Parsing Untrusted File Formats Safely). Wuffs...
-
67
A simple but safe upgrade path from Gson to Kotlin that lets you migrate your endpoints one-by-one.
-
43
Last week I have shared lessons learned scaling PostgreSQL database to 1.2bn records/month . In the...
-
24
easy-json-parse Are you still worried about the long code with try {} catch {} ? like this: const jsonString = 'easy'; let json; try { json = JSON.parse(jsonString); } catch (e) { j...
-
22
Safely receive files only you can open 🔑📄SafeRequest allows you to securely request files from others. Instead of sharing a public link to download files, you share a link to a personal upload page. Fi...
-
22
Django templates are often used to pass data to JavaScript code. Unfortunately, if implemented incorrectly, this opens up the po...
-
11
When developing music software, you are operating under tight time constraints. The time between subsequent audio processing callbacks is typically between 1-10 ms. A common default setting is a buffer size of 128 samples...
-
8
How to update nested state in ReactNick Scialli • June 10, 2021 • 🚀🚀 7 minute readIn React, we can update state using state setter functions. In function components, a state setter is pr...
-
3
-
3
How to safely update state in your Kotlin appsPublished in
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK