Bonjour, je suis débutant en react et j'ai souvent ce warning... Après quelque recherche j'ai essayé de le régler comme ceci (voir code) mais sans succès j'avoue ne pas comprendre comment s'en débarrasser.

Voici le message exact du warning :
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. at RenderConnexionView (https://localhost:3000/static/js/bundle.js:3001:80)
Merci d'avance pour votre aide.

Fichier useIsMounted.js :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
import {useEffect, useRef} from 'react'
 
export function useIsMounted() {
    const isMounted = useRef(false)
 
    useEffect(() => {
        isMounted.current = true
        return () => isMounted.current = false
    }, [])
 
    return isMounted
}
Fichier RenderConnexionView.js
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import React, {useEffect, useState} from "react"
import axios from 'axios'
import {useNavigate} from 'react-router'
import {useTranslation} from "react-i18next";
import ModalPopup from "../Modal/modal";
import {ConfirmModalView} from "../Modal/confirmModal";
import {ModalListConnexion} from "../Modal/modalListConnexion";
import {useIsMounted} from "../Utilities/useIsMounted";
 
function RenderConnexionView() {
	const [comment, setComment] = useState("")
	const [username, setUsername] = useState('')
	const [clientUserName, setClientUserName] = useState('')
	const [password, setPassword] = useState('')
	const [isLoading, setIsLoading] = useState(false)
	const [passwordView, setPasswordView] = useState("password")
	const [forceValue, setForceValue] = useState(false)
	const [modalLogout, setModalLogout] = useState(false)
	const [modalListConnections, setModalListConnections] = useState(false)
	const {t, i18n} = useTranslation()
	const isMounted = useIsMounted()
	let navigate = useNavigate()
 
	const loginUser = async (forceLogout) => {
		let data = {
			username: username,
			password: password,
			tenant: clientUserName,
			force: forceLogout,
			application: "e-data"
		}
 
		if(isMounted.current) {
			await axios.post('/authentication/login', data, {
				doNotCatch: true
			}).then(res => {
				window.localStorage.setItem('token', res.data)
				navigate("/dashboard")
			}).catch(error => {
				if (error.response.status == 409) {
					setModalLogout(true)
				} else if (error.response.status == 429) {
					if (error.response.data.status)
						return alert(t("connection_limit"))
					window.localStorage.setItem('token', error.response.data)
					setModalListConnections(true)
				} else {
					setComment(t("connection_error"))
				}
			}).finally(() => {
				setIsLoading(false)
			})
		}
	}
 
	const handleUserNameChange = event => {
		setUsername(event.target.value)
	}
	const handlePasswordChange = event => {
		setPassword(event.target.value)
	}
	const handleClientUsernameChange = event => {
		setClientUserName(event.target.value)
	}
	const handlePasswordViewChange = event => {
		if (passwordView == "password")
			setPasswordView("text")
		else
			setPasswordView("password")
	}
	const confirmLogout = () => {
		loginUser(true)
	}
	const handleSubmit = async event => {
		setIsLoading(true)
		event.preventDefault()
		await loginUser(false)
 
	}
	useEffect(async () => {
		if(isMounted.current) {
			await axios.post('/authentication/disconnect', {}, {doNotCatch: true})
		}
		window.localStorage.setItem('token', null)
	}, [])
 
	return (
		<div className="connexion-color h-100 d-flex align-items-center justify-content-center flex-direction-column">
			<div className="box-connexion p-3">
				<div className="box-logo-e-data text-center">
					<svg enableBackground="new 0 0 80 80" version="1.1" viewBox="0 0 80 80"
						 className="logo-e-data-login">
						<linearGradient id="a" x1="7.3067" x2="72.852" y1="52.836" y2="52.836"
										gradientTransform="matrix(1 0 0 -1 0 82)" gradientUnits="userSpaceOnUse">
							<stop stopColor="#77C5B7" offset=".2976"/>
							<stop stopColor="#72C4BA" offset=".3848"/>
							<stop stopColor="#43BAC2" offset="1"/>
						</linearGradient>
						<path className="st5" d="m18.9 17.6v-2.9h2.9v2.9h-2.9zm-2.9 0v2.9h2.9v-2.9h-2.9zm-2.8 5.8h2.8v-2.9h-2.9v2.9zm2.8 5.7h2.9v-2.9h-2.9v2.9zm0 23.2h-2.9v2.9h2.9v-2.9h2.9v-2.9h-2.9v2.9zm-2.8-20.2v2.9h2.8v-2.9h-2.8zm-5.9-8.7h2.9v-2.9h-2.9v2.9zm5.9-8.7h-5.9v3h2.9v2.9h2.8v-5.9h0.2zm0-8.6v2.9h2.8v-2.9h-2.8zm-3 0h-2.9v2.9h2.9v-2.9zm8.7-2.9v2.9h2.9v-2.9h-2.9zm54 26c0 4.6-1.1 9-3.4 13-2.2 4.1-5.5 7.2-9.8 9.5s-9.5 3.3-15.7 3.3h-16.4v-2.9h2.9v-2.9h-2.9v2.9h-2.9v-5.7h-2.9v-2.9h-3v2.9h-5.7v-2.9h-3v-2.9h2.9v2.9h5.9v-2.9h2.9v2.9h2.9v2.9h3v-5.7h-5.8v-2.9h-5.9v-2.8h2.9v-2.9h2.9v2.9h2.9v-3h-2.9v-5.8h2.9v-2.9h-2.9v2.9h-2.9v-5.8h2.9v-2.9h2.9v-2.9h-2.9v-3h-2.9v2.9h-5.8v-2.9h2.9v-2.7h5.8v-2.8h2.9v-2.9h3v2.9h-2.9v2.9h2.9v-2.9h2.9v-2.9h14.2c9.1 0 15.9 2.5 20.9 7.6 4.8 5.1 7.2 11.2 7.2 18.4zm-42.4-17.3v2.9h2.9v-2.9h-2.9zm-2.9 0h2.9v-2.8h-2.9v2.8zm0 11.5v2.9h2.9v-2.9h-2.9v-2.9h2.9v-2.9h-2.9v2.9h-2.9v3h2.9v-0.1zm2.9 2.8v2.9h2.9v-2.9h-2.9zm0 11.6h-2.9v2.9h2.9v-2.9zm2.8-2.8v-2.9h-2.9v2.9h2.9zm2.9 8.7h-2.9v2.9h2.9v-2.9zm18.7-14.7c0-8.3-4.7-12.6-14.3-12.6h-3v25.7h1.2c5.7 0 9.8-1 12.3-3 2.5-2.2 3.8-5.5 3.8-10.1zm-27.3-5.6zm0 28.9z"/>
						<path className="st1" d="m10 65c2.9 0 4 1.4 4 3.6s-1.1 3.4-4 3.4h-5.6v0.9c0 1 0.5 1.6 1.9 1.6h7.2v2.4h-7.3c-3 0-4.1-1.6-4.1-3.9v-4.1c0-2.2 1.1-3.9 4.1-3.9h3.8zm-5.6 5.2h5.6c1.2 0 1.7-0.5 1.7-1.4s-0.5-1.5-1.7-1.5h-3.8c-1.2 0-1.9 0.7-1.9 1.6v1.2h0.1z"/>
						<path className="st1" d="M24,68.6v2.2h-8.1v-2.2H24z"/>
						<path className="st1" d="m33.1 61.6c4.5 0 6.9 2.5 6.9 7.6s-2.4 7.6-6.9 7.6h-5.4c-0.9 0-1.2-0.4-1.2-1.2v-12.7c0-0.9 0.4-1.2 1.2-1.2h5.4zm-3.9 12.3c0 0.2 0.1 0.2 0.2 0.2h3.6c3 0 4.2-1.5 4.2-5s-1.2-5-4.2-5h-3.6c-0.2 0-0.2 0.1-0.2 0.2v9.6z"/>
						<path className="st1" d="m50.2 65c3 0 4.1 1.6 4.1 3.9v5.6c0 1.7-0.5 2.4-2.5 2.4h-5.5c-2.9 0-4-1.4-4-3.6 0-2.1 1.1-3.4 4-3.4h5.6v-0.9c0-0.9-0.5-1.6-1.9-1.6h-7.1v-2.4h7.3zm1.8 8.9v-2.2h-5.6c-1.2 0-1.7 0.5-1.7 1.4s0.5 1.5 1.6 1.5h5c0.5 0 0.7-0.3 0.7-0.7z"/>
						<path className="st1" d="m58.1 65v-2.9h2.4v2.9h3.2v2.2h-3.2v5.6c0 1.4 0.5 1.7 1.6 1.7h1.6v2.2h-2.1c-2.5 0-3.5-1-3.5-4.1v-5.5h-1.6v-2.1h1.6z"/>
						<path className="st1" d="m73.8 65c3 0 4.1 1.6 4.1 3.9v5.6c0 1.7-0.5 2.4-2.5 2.4h-5.4c-2.9 0-4-1.4-4-3.6 0-2.1 1.1-3.4 4-3.4h5.6v-0.9c0-0.9-0.5-1.6-1.9-1.6h-7.1v-2.4h7.2zm1.8 8.9v-2.2h-5.6c-1.2 0-1.7 0.5-1.7 1.4s0.5 1.5 1.6 1.5h5c0.5 0 0.7-0.3 0.7-0.7z"/>
					</svg>
				</div>
				<form onSubmit={handleSubmit}>
					<h1 className="pb-5 m-0">{t("login:header")}</h1>
					<div className="identifiant-client">
						<label htmlFor="username-client" className="d-block"><b>{t("login:client_id")}</b></label>
						<input type="text" name="username-client" onChange={handleClientUsernameChange}
							   className="w-100" required/>
					</div>
					<div className="pb-3">
						<label htmlFor="username" className="d-block"><b>{t("login:user")}</b></label>
						<input type="text" onChange={handleUserNameChange} name="username" className="w-100" required/>
					</div>
					<div className="pb-5">
						<label htmlFor="password" className="d-block"><b>{t("login:password")}</b></label>
						<div className="position-relative">
							<input type={passwordView} onChange={handlePasswordChange} name="password" className="w-100"
								   required/>
							<input type="checkbox" onChange={handlePasswordViewChange} id="show-password"
								   className="show-password-checkbox"/>
							<label htmlFor="show-password" className="show-password pb-0 d-flex align-items-center">
								<svg enableBackground="new 0 0 60 60" version="1.1" viewBox="0 0 60 60">
									<path
										d="m30 19.8c-0.9 0-1.8 0.2-2.6 0.4 1.5 0.8 2.4 2.4 2.4 4.2 0 2.7-2.1 4.9-4.7 4.9-1.6 0-3.1-0.9-3.9-2.1-0.1 0.5-0.2 1.1-0.2 1.6 0 4.9 4 9 9 9s9-4 9-9-4.1-9-9-9z"/>
									<path
										d="m54.8 23.7c-5.3-4.9-14.4-11.6-24.8-11.6s-19.5 6.7-24.8 11.6c-3.1 2.9-3.1 7.2 0 10.1 5.3 4.9 14.4 11.6 24.8 11.6s19.5-6.7 24.8-11.6c3.1-2.8 3.1-7.2 0-10.1zm-24.8 17.9c-7.1 0-12.8-5.7-12.8-12.8s5.7-12.8 12.8-12.8 12.8 5.7 12.8 12.8c0 7-5.7 12.8-12.8 12.8z"/>
									<path className="fill-white"
										  d="m30 16c-7.1 0-12.8 5.7-12.8 12.8s5.7 12.8 12.8 12.8 12.8-5.7 12.8-12.8-5.7-12.8-12.8-12.8zm0 21.8c-4.9 0-9-4-9-9 0-0.5 0.1-1.1 0.2-1.6 0.9 1.3 2.3 2.1 3.9 2.1 2.6 0 4.7-2.2 4.7-4.9 0-1.8-1-3.4-2.4-4.2 0.8-0.3 1.7-0.4 2.6-0.4 4.9 0 9 4 9 9s-4.1 9-9 9z"/>
 
									<path className="ligne-oeil"
										  d="m49 55.3c-1.3 0-2.5-0.5-3.4-1.4l-41.1-41c-1.9-1.9-1.9-4.9 0-6.8 0.9-0.9 2.1-1.4 3.4-1.4s2.5 0.5 3.4 1.4l41.1 41.1c1.9 1.9 1.9 4.9 0 6.8-0.9 0.8-2.2 1.3-3.4 1.3z"/>
									<path className="fill-white ligne-oeil-blanc"
										  d="m7.9 7.5c0.5 0 1 0.2 1.4 0.6l41.1 41.1c0.7 0.7 0.7 2 0 2.7-0.4 0.4-0.9 0.6-1.4 0.6s-1-0.2-1.4-0.6l-41.1-41.1c-0.7-0.7-0.7-2 0-2.7 0.4-0.4 0.9-0.6 1.4-0.6m0-5.7c-2.1 0-4 0.8-5.4 2.2-3 3-3 7.9 0 10.9l41 41.1c1.5 1.5 3.4 2.2 5.4 2.2 2.1 0 4-0.8 5.4-2.2 3-3 3-7.9 0-10.9l-41-41.1c-1.4-1.4-3.4-2.2-5.4-2.2z"/>
								</svg>
							</label>
						</div>
						<p className="color-red mb-0">{comment}</p>
					</div>
					<button type="submit" id="submit"
							className={isLoading ? "bouton-connexion bouton px-10 pt-1 pb-1 loading" : "bouton-connexion bouton px-10 pt-1 pb-1"}>{isLoading ?
						<span className="spinner"></span> : t("proceed")}</button>
				</form>
			</div>
			<p className="fw-bold copyright mb-0">© IMPLEX 2022</p>
			{modalLogout ?
				<ModalPopup propsAdd={{
					function: confirmLogout,
					id: 0,
					txt: t("already_connected"),
					title: t("query:confirmation")
				}}
							closeCLicked={false}
							content={ConfirmModalView}
							setShowModal={setModalLogout}/> : null}
			{modalListConnections ?
				<ModalPopup propsAdd={{}}
							closeCLicked={false}
							content={ModalListConnexion}
							setShowModal={setModalListConnections}/> : null}
		</div>
 
	)
}
 
 
export default RenderConnexionView