this article is used to record some of the author's gains in the section strict mode
in the official React18 documentation, concerning the role of strict mode, why React executes useEffect twice, and how to optimize it.
strict mode (Strict Mode)
what is strict mode
strict mode is a tool to check for possible problems in your application. Strict mode only runs in a development environment, but it has no impact in a production environment.
import React from 'react';
function ExampleApplication() {
return (
<div>
<Header />
<React.StrictMode> <div>
<ComponentOne />
<ComponentTwo />
</div>
</React.StrictMode> <Footer />
</div>
);
}
you can use React.StrictMode
to wrap the apps you want to check. Apps without packages will not be affected. For example, the & lt;Header / & gt;
component in the above code will not be affected by the strict mode, only the & lt;ComponentOne / & gt;
and & lt;ComponentTwo>
that we package will be affected by the strict mode.
the role of strict mode
strict mode makes the following checks
- identify unsafe lifecycles, such as componentWillMount. Later, it was upgraded to componentDidMount
- check on ref, a previous version of API, I hope you can replace it with a new version
- warning of findDOMNode being deprecated
- detect unexpected side effects
- found API with expired context
- ensure reusable state
ReactThe official document of React provides an example, which should mean that if we jump from Route A to Route B and then return from Route B.
ReactI hope to immediately display the original state, so that I can cache the state of A, so that when we return, we can immediately render it based on the state in the cache.
Why does React set useEffect to execute twice
We just mentioned that React will support remounting to the tree using the state of the components that existed before the uninstall. However, components are required to be resilient to the side effects of multiple mounts and destruction. Here we need to have a good understanding of the side effects of React, and the author has not fully understood the meaning of this sentence, but we can understand the usage scenario of useEffect according to the examples given in the official React documentation, and then come back to understand the meaning of this sentence.
seems to mean that if React does not set Effect to execute twice, then React may cause some problems when doing this optimization. And these problems will not be noticed by developers, so React set Effect to execute twice in order to expose the problem in advance. React also believes that Effect execution twice is no problem in most cases
non-strict mode
* React mounts the component. //Mount components
* Layout effects are created. //Layout Execution
* Effects are created. //Effects Execution
strict mode
* React mounts the component. //Mount components
* Layout effects are created. //layout Execution
* Effect effects are created. // Effects Execution
* React simulates effects being destroyed on a mounted component. //React simulation component destruction
* Layout effects are destroyed. // Layout Destroy
* Effects are destroyed. // Effects Destroy
* React simulates effects being re-created on a mounted component. // React simulates remounting
* Layout effects are created // Layout Recreate
* Effect setup code runs // Effect re execution
how to deal with the problem of Effect execution twice in the application
React believes that executing twice doesn't make a difference in most cases, and we should consider how to get Effect to execute correctly after remounting, rather than how to get Effect to execute once. Let's take a look at some optimized scenarios.
request data
We can use a variable to control that the request is sent only once, or we can improve it by canceling the request.
useEffect(() => {
let ignore = false;
async function startFetching() {
const json = await fetchTodos(userId);
if (!ignore) {
setTodos(json);
}
}
startFetching();
return () => {
ignore = true;
};
}, [userId]);
pop-up window problem
remove the pop-up window close before the second mount, and there will be no problem of calling showModal () twice
useEffect(() => {
const dialog = dialogRef.current;
dialog.showModal();
return () => dialog.close();
}, []);
Not an Effect: Buying a product
I don't know how to translate the title. Just bring it over and use it
.
useEffect(() => {
fetch('/api/buy', { method: 'POST' });
}, []);
React believes that it is incorrect to send a post request in useEffect, and this requirement scenario does not exist. You should send a post request in a click event, not directly in the useEffect.
setTimeout
remember to cancel the timer in useEffect
useEffect(() => {
function onTimeout() {
console.log('⏰ ' + text);
}
console.log('⏰ Schedule "' + text + '" log');
const timeoutId = setTimeout(onTimeout, 3000);
return () => {
console.log('⏰ Cancel "' + text + '" log');
clearTimeout(timeoutId);
};
}, [text]);
Comments