Tôi mới sử dụng React, vì vậy điều này có thể thực sự đơn giản để đạt được nhưng tôi không thể tự mình tìm ra nó mặc dù tôi đã thực hiện một số nghiên cứu. Hãy tha thứ cho tôi nếu điều này quá ngu ngốc.
Bối cảnh
Tôi đang sử dụng Inertia.js với bộ điều hợp Laravel (phụ trợ) và React (front-end). Nếu bạn không biết quán tính, về cơ bản:
Inertia.js cho phép bạn nhanh chóng xây dựng các ứng dụng React, Vue và Svelte một trang hiện đại bằng cách sử dụng bộ điều khiển và định tuyến phía máy chủ cổ điển.
Vấn đề
Tôi đang làm một trang đăng nhập đơn giản có một biểu mẫu mà khi gửi sẽ thực hiện yêu cầu POST để tải trang tiếp theo. Nó có vẻ hoạt động tốt nhưng trong các trang khác, bảng điều khiển hiển thị cảnh báo sau:
Cảnh báo: Không thể thực hiện cập nhật trạng thái Phản ứng trên một thành phần chưa từng có. Đây là một no-op, nhưng nó chỉ ra rò rỉ bộ nhớ trong ứng dụng của bạn. Để khắc phục, hủy tất cả các đăng ký và tác vụ không đồng bộ trong chức năng dọn dẹp useEffect.
trong đăng nhập (được tạo bởi quán tính)
Mã liên quan (Tôi đã đơn giản hóa nó để tránh các dòng không liên quan):
import React, { useEffect, useState } from 'react'
import Layout from "../../Layouts/Auth";
{/** other imports */}
const login = (props) => {
const { errors } = usePage();
const [values, setValues] = useState({email: '', password: '',});
const [loading, setLoading] = useState(false);
function handleSubmit(e) {
e.preventDefault();
setLoading(true);
Inertia.post(window.route('login.attempt'), values)
.then(() => {
setLoading(false); // Warning : memory leaks during the state update on the unmounted component <--------
})
}
return (
<Layout title="Access to the system">
<div>
<form action={handleSubmit}>
{/*the login form*/}
<button type="submit">Access</button>
</form>
</div>
</Layout>
);
};
export default login;
Bây giờ, tôi biết rằng tôi phải thực hiện chức năng dọn dẹp vì lời hứa của yêu cầu là thứ tạo ra cảnh báo này. Tôi biết rằng tôi nên sử dụng useEffect
nhưng tôi không biết làm thế nào để áp dụng nó trong trường hợp này. Tôi đã thấy ví dụ khi một giá trị thay đổi, nhưng làm thế nào để thực hiện nó trong một cuộc gọi loại này?
Cảm ơn trước.
Cập nhật
Theo yêu cầu, mã đầy đủ của thành phần này:
import React, { useState } from 'react'
import Layout from "../../Layouts/Auth";
import { usePage } from '@inertiajs/inertia-react'
import { Inertia } from "@inertiajs/inertia";
import LoadingButton from "../../Shared/LoadingButton";
const login = (props) => {
const { errors } = usePage();
const [values, setValues] = useState({email: '', password: '',});
const [loading, setLoading] = useState(false);
function handleChange(e) {
const key = e.target.id;
const value = e.target.value;
setValues(values => ({
...values,
[key]: value,
}))
}
function handleSubmit(e) {
e.preventDefault();
setLoading(true);
Inertia.post(window.route('login.attempt'), values)
.then(() => {
setLoading(false);
})
}
return (
<Layout title="Inicia sesión">
<div className="w-full flex items-center justify-center">
<div className="w-full max-w-5xl flex justify-center items-start z-10 font-sans text-sm">
<div className="w-2/3 text-white mt-6 mr-16">
<div className="h-16 mb-2 flex items-center">
<span className="uppercase font-bold ml-3 text-lg hidden xl:block">
Optima spark
</span>
</div>
<h1 className="text-5xl leading-tight pb-4">
Vuelve inteligente tus operaciones
</h1>
<p className="text-lg">
Recoge data de tus instalaciones de forma automatizada; accede a información histórica y en tiempo real
para que puedas analizar y tomar mejores decisiones para tu negocio.
</p>
<button type="submit" className="bg-yellow-600 w-40 hover:bg-blue-dark text-white font-semibold py-2 px-4 rounded mt-8 shadow-md">
Más información
</button>
</div>
<div className="w-1/3 flex flex-col">
<div className="bg-white text-gray-700 shadow-md rounded rounded-lg px-8 pt-6 pb-8 mb-4 flex flex-col">
<div className="w-full rounded-lg h-16 flex items-center justify-center">
<span className="uppercase font-bold text-lg">Acceder</span>
</div>
<form onSubmit={handleSubmit} className={`relative ${loading ? 'invisible' : 'visible'}`}>
<div className="mb-4">
<label className="block text-gray-700 text-sm font-semibold mb-2" htmlFor="email">
Email
</label>
<input
id="email"
type="text"
className=" appearance-none border rounded w-full py-2 px-3 text-gray-700 mb-3 outline-none focus:border-1 focus:border-yellow-500"
placeholder="Introduce tu e-mail.."
name="email"
value={values.email}
onChange={handleChange}
/>
{errors.email && <p className="text-red-500 text-xs italic">{ errors.email[0] }</p>}
</div>
<div className="mb-6">
<label className="block text-gray-700 text-sm font-semibold mb-2" htmlFor="password">
Contraseña
</label>
<input
className=" appearance-none border border-red rounded w-full py-2 px-3 text-gray-700 mb-3 outline-none focus:border-1 focus:border-yellow-500"
id="password"
name="password"
type="password"
placeholder="*********"
value={values.password}
onChange={handleChange}
/>
{errors.password && <p className="text-red-500 text-xs italic">{ errors.password[0] }</p>}
</div>
<div className="flex flex-col items-start justify-between">
<LoadingButton loading={loading} label='Iniciar sesión' />
<a className="font-semibold text-sm text-blue hover:text-blue-700 mt-4"
href="#">
<u>Olvidé mi contraseña</u>
</a>
</div>
<div
className={`absolute top-0 left-0 right-0 bottom-0 flex items-center justify-center ${!loading ? 'invisible' : 'visible'}`}
>
<div className="lds-ellipsis">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</form>
</div>
<div className="w-full flex justify-center">
<a href="https://optimaee.com">
</a>
</div>
</div>
</div>
</div>
</Layout>
);
};
export default login;
.then(() => {})
?