ฉันใหม่โดยใช้ React ดังนั้นนี่อาจเป็นเรื่องง่ายที่จะประสบความสำเร็จ แต่ฉันไม่สามารถหาคำตอบได้ด้วยตัวเองแม้ว่าฉันจะทำวิจัยแล้วก็ตาม ยกโทษให้ฉันถ้านี่มันโง่เกินไป
บริบท
ฉันใช้Inertia.jsกับอะแดปเตอร์ Laravel (แบ็กเอนด์) และ React (front-end) หากคุณไม่รู้จักความเฉื่อยมันเป็นเรื่องปกติ:
Inertia.js ให้คุณสร้างแอป React, Vue และ Svelte แบบหน้าเดียวที่ทันสมัยได้อย่างรวดเร็วโดยใช้การกำหนดเส้นทางและตัวควบคุมฝั่งเซิร์ฟเวอร์แบบคลาสสิก
ปัญหา
ฉันกำลังทำหน้าเข้าสู่ระบบแบบง่ายที่มีแบบฟอร์มที่เมื่อส่งจะทำการร้องขอ POST เพื่อโหลดหน้าถัดไป ดูเหมือนว่าจะทำงานได้ดี แต่ในหน้าอื่น ๆ คอนโซลจะแสดงคำเตือนต่อไปนี้:
คำเตือน: ไม่สามารถทำการอัพเดทสถานะทำปฏิกิริยากับส่วนประกอบที่ไม่ได้ประกอบเข้าไป นี่คือไม่ใช้งาน แต่ระบุว่ามีหน่วยความจำรั่วในแอปพลิเคชันของคุณ ในการแก้ไขให้ยกเลิกการสมัครสมาชิกและงานอะซิงโครนัสทั้งหมดในฟังก์ชัน useEffect cleanup
ในการเข้าสู่ระบบ (สร้างโดย Inertia)
รหัสที่เกี่ยวข้อง (ฉันได้ง่ายขึ้นเพื่อหลีกเลี่ยงบรรทัดที่ไม่เกี่ยวข้อง):
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;
ตอนนี้ฉันรู้ว่าฉันต้องทำฟังก์ชั่นการล้างข้อมูลเพราะสัญญาของคำขอคือสิ่งที่สร้างคำเตือนนี้ ฉันรู้ว่าฉันควรใช้useEffect
แต่ฉันไม่รู้วิธีใช้ในกรณีนี้ ฉันเคยเห็นตัวอย่างเมื่อมีการเปลี่ยนแปลงค่า แต่วิธีการในการเรียกชนิดนี้หรือไม่?
ขอบคุณล่วงหน้า.
ปรับปรุง
ตามที่ขอรหัสเต็มขององค์ประกอบนี้:
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(() => {})
?