# #reactjs #firebase-authentication
Вопрос:
Поскольку я новичок в ReactJS, я не могу понять, почему я получаю это «Предупреждение: Не удается выполнить обновление состояния реакции для размонтированного компонента. Это не операция, но это указывает на утечку памяти в вашем приложении. Чтобы исправить это, отмените все подписки и асинхронные задачи в функции очистки useEffect». после регистрации и входа в систему. Вот мой код следующим образом:
AuthContext.js:
import React, { useContext, useState, useEffect } from "react";
import { auth } from "../firebase";
const AuthContext = React.createContext();
export function useAuth() {
return useContext(AuthContext);
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState();
const [loading, setLoading] = useState(true);
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password);
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
setCurrentUser(user);
setLoading(false);
});
return unsubscribe;
}, []);
const value = {
currentUser,
login,
signup,
};
return (
<AuthContext.Provider value={value}>
{!loading amp;amp; children}
</AuthContext.Provider>
);
}
Signup.js:
import React, { useRef, useState } from "react";
import { useAuth } from "../contexts/AuthContext";
import { Link, useHistory } from "react-router-dom";
export default function Signup() {
const emailRef = useRef();
const passwordRef = useRef();
const passwordConfirmRef = useRef();
const { signup } = useAuth();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const history = useHistory();
async function handleSubmit(e) {
e.preventDefault();
if (passwordRef.current.value !== passwordConfirmRef.current.value) {
return setError("Passwords do not match");
}
try {
setError("");
setLoading(true);
await signup(emailRef.current.value, passwordRef.current.value);
history.push("/login");
} catch (e) {
console.error(e);
}
setLoading(false);
}
return (
<div>
<div
className="h-screen overflow-hidden flex
items-center justify-center bg-blue-300"
>
<form
onSubmit={handleSubmit}
className="space-y-5 bg-white p-16 rounded shadow w-2/3"
>
<h2 className="text-3xl mb-5 text-center text-gray-800">Sign Up</h2>
<hr />
<div class="bg-teal-200 relative text-teal-600 py-3 px-3 rounded-lg">
{error}
</div>
<label
htmlFor="email"
className="block mb-1 font-mono mt-3 text-gray-500"
>
Email
</label>
<input
ref={emailRef}
type="email"
name="email"
placeholder="Email"
className="w-full border-2 border-gray-200 p-3
rounded outline-none focus:border-blue-300"
required
/>
<label
htmlFor="password"
className="block mb-1 font-mono mt-3 text-gray-500"
>
Password
</label>
<input
ref={passwordRef}
type="password"
name="password"
placeholder="Password"
className="w-full border-2 border-gray-200 p-3
rounded outline-none focus:border-blue-300"
required
/>
<label
htmlFor="confirm password"
className="block mb-1 font-mono mt-3 text-gray-500"
>
Confirm Password
</label>
<input
ref={passwordConfirmRef}
type="password"
name="confirm-password"
placeholder="Retype Password"
className="w-full border-2 border-gray-200 p-3
rounded outline-none focus:border-blue-300"
required
/>
<hr />
<button
disabled={loading}
type="submit"
className="block w-full bg-pink-400 hover:bg-pink-300 p-4
rounded text-blck transition duration-300 font-semibold"
>
SIGN UP
</button>
<div className="w-100 text-center mt-2">
Already have an account?{" "}
<Link className="text-blue-600" to="/login">
Log In
</Link>
</div>
</form>
</div>
</div>
);
}
Login.js:
import React, { useRef, useState } from "react";
import { useAuth } from "../contexts/AuthContext";
import { Link, useHistory } from "react-router-dom";
export default function Login() {
const emailRef = useRef();
const passwordRef = useRef();
const { login } = useAuth();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const history = useHistory();
async function handleSubmit(e) {
e.preventDefault();
try {
setError("");
setLoading(true);
await login(emailRef.current.value, passwordRef.current.value);
history.push("/appointments");
} catch (e) {
console.error(e);
}
setLoading(false);
}
return (
<div>
<div
className="h-screen overflow-hidden flex
items-center justify-center bg-blue-300"
>
<form
onSubmit={handleSubmit}
className="space-y-5 bg-white p-16 rounded shadow w-2/3"
>
<h2 className="text-3xl mb-5 text-center text-gray-800">Log In</h2>
<hr />
<div class="bg-teal-200 relative text-teal-600 py-3 px-3 rounded-lg">
{error}
</div>
<label
htmlFor="email"
className="block mb-1 font-mono mt-3 text-gray-500"
>
Email
</label>
<input
ref={emailRef}
type="email"
name="email"
placeholder="Email"
className="w-full border-2 border-gray-200 p-3
rounded outline-none focus:border-blue-300"
/>
<label
htmlFor="password"
className="block mb-1 font-mono mt-3 text-gray-500"
>
Password
</label>
<input
ref={passwordRef}
type="password"
name="password"
placeholder="Password"
className="w-full border-2 border-gray-200 p-3
rounded outline-none focus:border-blue-300"
/>
<button
disabled={loading}
type="submit"
className="block w-full bg-pink-400 hover:bg-pink-300 p-4
rounded text-blck transition duration-300 font-semibold"
>
LOG IN
</button>
<div className="w-100 text-center mt-2">
Need an account?{" "}
<Link className="text-blue-500" to="/register">
Sign Up
</Link>
</div>
</form>
</div>
</div>
);
}
Ответ №1:
Просто потому, что вы не сделали обратный вызов после возврата в useEffet, что означает, что ваш крючок useEffect должен быть таким:
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
if (user) {
setCurrentUser(user);
}
setLoading(false);
});
return () => unsubscribe();
}, []);
Комментарии:
1. Он все еще дает то же самое предупреждение
2. @bhuvana проблема в том, что вы обновляете состояние во время размонтирования компонента, что не подходит для вашего компонента, пожалуйста, внесите изменения в свой код и удалите логику, которой вы можете избежать(обновите состояние, когда компонент размонтирован, я имею в виду в функции возврата крючка useEffect).