Если вы недавно создали новый проект с помощью Create React App
или обновились до React версии 18, вы увидите, что хук useEffect выполняется дважды в режиме разработки.
Если вы новичок в использовании хука useEffect, вы можете прочитать одну из моих предыдущих статей: полное руководство по использованию хука useEffect.
Воспроизведение проблемы
Создайте новое приложение react с помощью следующей команды:
npx create-react-app react-use-effect-twice
Обновите App.js
следующим кодом:
import { useEffect } from "react"
function App() {
useEffect(() => {
console.log("useEffect executed (component mounted)")
}, [])
return <div className="App"></div>
}
export default App
Здесь у нас есть хук useEffect, и мы регистрируем сообщение внутри него.
Если вы запустите приложение и откроете консоль браузера, вы увидите, что сообщение отображается дважды.
Понимание проблемы
В StrictMode, начиная с React 18, в режиме разработки эффекты будут монтироваться, размонтироваться и снова монтироваться.
Это происходит только в режиме разработки, но не в режиме производства.
Это было добавлено, чтобы помочь React в будущем ввести функцию, когда он сможет добавить или удалить секцию пользовательского интерфейса с сохранением состояния. Например, при переключении между вкладками сохранение состояния предыдущей вкладки помогает предотвратить ненужное выполнение эффектов, таких как вызовы API.
Мы можем подтвердить это поведение, добавив функцию очистки в хук useEffect:
import { useEffect } from "react"
function App() {
useEffect(() => {
console.log("useEffect executed (component mounted)")
return () => {
console.log("useEffect cleanup (component unmounted)")
}
}, [])
return <div className="App"></div>
}
export default App
Если вы запустите приложение, то увидите следующие сообщения в консоли браузера:
Устранение проблемы
Если вы читали предыдущий раздел, это не совсем проблема. Следовательно, она не требует исправления.
Если вы все же хотите, чтобы useEffect не вызывался дважды, вы можете удалить тег <StickMode>
из файла index.js
.