리μ‘νΈλ₯Ό μ΄μ©νμ¬ λͺ¨λ¬ μ»΄ν¬λνΈλ₯Ό κ°λ° νλμ€ λ€μκ³Ό κ°μ μλ¬κ° λ°μνμλ€.
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.
κ²½κ³ ! μΈλ§μ΄ν°λλ μ»΄ν¬λνΈμ λν΄μλ μν μ
λ°μ΄νΈλ₯Ό μνν μ μλ€.
ν΄λΉ μμ
μ μνλμ§ μμ§λ§ λ©λͺ¨λ¦¬ λμκ° λ°μλλ€.
ν΄κ²°λ°©λ²μΌλ‘ useEffect
μ cleanup functionμ μ΄μ©ν΄λΌ
μ½μμ°½μ λΉ¨κ°κΈμ¨λ‘ κ²½κ³ λ©μΈμ§κ° λμ€λ©΄ νμ π‘μ§μ¦μ΄ λμ§λ§ μΉμ νκ² μλ¬ λ©μΈμ§ μμλ ν΄κ²°λ°©λ²μ μλ €μ€λ€.
ν΄λΉ μλ¬κ° λ°μν μν©μ λΉλκΈ° μμ
μ μ²λ¦¬νλ κ³Όμ μμ λ°μνμλ€. λΉλκΈ° μμ
μ μννκΈ° μ μ loading
μ΄λΌλ μνλ³μλ₯Ό true
λ‘ λ³κ²½νμ¬ νμ¬ λ‘λ©μ€μ΄λΌλ λͺ¨μ΅μ 보μ¬μ£Όμκ³ λΉλκΈ° μμ
μ΄ μλ£λ κ²½μ° λͺ¨λ¬ μ»΄ν¬λνΈκ° μ¬λΌμ§κ³ loading
μ΄λΌλ μνλ³μλ₯Ό false
λ‘ λ³κ²½νμλ€. μ΄ κ³Όμ μμ μμ κ°μ μλ¬κ° λ°μνμλ€. λͺ¨λ¬ μ»΄ν¬λνΈκ° μ¬λΌμ§ μ΄νμκΈ° λλ¬Έμ loading
μνλ³μλ₯Ό κ΄λ¦¬νλ μ»΄ν¬λνΈκ° μ¬λΌμ‘κΈ° λλ¬Έμ μνλ³μλ₯Ό μ
λ°μ΄νΈ ν μ μλ€λ μλ¬μλ€. λ¬Όλ‘ μ»΄ν¬λνΈκ° μ¬λΌμ§λ©΄ ν΄λΉ μ»΄ν¬λνΈκ° κ΄λ¦¬νλ λͺ¨λ μνλ³μλ μ²μμΌλ‘ λμκ°κΈ° λλ¬Έμ loading
μ΄λΌλ μνλ³μλ₯Ό false
λ‘ κ΅³μ΄ λ³κ²½νμ§ μμλ λκΈ° λλ¬Έμ μνλ³μλ₯Ό false
λ‘ λ°κΎΈμ§ μμλ λμ§λ§ false
λ‘ λ°κΎΈκ³ μΆμ κ²½μ° μ΄λ»κ² ν΄μΌνλμ§ μκ³ μΆμλ€.
μλ¬κ° λ°μν μν©μ κ°λ΅ν μ½λλ‘ μμ±ν΄ 보μλ€.
import React, { useState } from "react";
import "./App.css";
import Modal from "./Modal";
const App = () => {
const [visible, setVisible] = useState(false);
const onClick = () => {
setVisible(true);
};
return (
<div className="App-container">
{visible && <Modal setVisible={setVisible} />}
<button className="App-modal-button" onClick={onClick}>
λͺ¨λ¬
</button>
</div>
);
};
export default App;
import React, { useState, useEffect } from "react";
import "./Modal.css";
const Modal = ({ setVisible }) => {
const [loading, setLoading] = useState(false);
const threeSecods = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("success");
}, 3000);
});
};
const onClick = () => {
setLoading(true);
threeSecods()
.then(res => {
if (res === "success") {
setVisible(false);
}
})
.then(() => setLoading(false));
};
return (
<div className="modal-back">
<div className="modal-container">
{loading && <span>Loading...</span>}
<button className="modal-close" onClick={onClick}>
λ«κΈ°
</button>
</div>
</div>
);
};
export default Modal;
1) κ°μ₯ κ°λ¨ν ν΄κ²°λ°©λ²μΌλ‘λ λͺ¨λ¬ μ»΄ν¬λνΈκ° μ¬λΌμ§λ μμ μ΄μ μ loading
μ΄λΌλ λ³μλ₯Ό false
λ‘ λ³κ²½νκ³ λͺ¨λ¬ μ»΄ν¬λνΈλ₯Ό μ¬λΌμ§κ² νλ κ²μ΄λ€.
const onClick = () => {
setLoading(true);
threeSecods().then(res => {
if (res === "success") {
setLoading(false); // λ‘λ© μνλ³μ λ³κ²½
setVisible(false); // λͺ¨λ¬ μ»΄ν¬λνΈ μ’
λ£
}
});
};
2) λ€μ λ°©λ²μΌλ‘λ μ½μμ°½μμ μλ €μ€ λ°©λ²μΌλ‘ useEffect
μ cleanup functionμ μ΄μ©νλ κ²μ΄λ€.
const onClick = () => {
setLoading(true);
threeSecods().then(res => {
if (res === "success") {
setVisible(false);
}
});
};
useEffect(() => {
return () => setLoading(false); // cleanup functionμ μ΄μ©
}, []);
μ΄λ»κ² μκ°νλ©΄ κ°λ¨ν μ€λ₯μ§λ§ μ»΄ν¬λνΈ μνκ°μ μ²λ¦¬νλ κ³Όμ μμ λꡬλ μ§ μ½κ² λ°μν μ μλ μλ¬λΌκ³ μκ°νμλ€.
λμ μ£Όμ μ κ°μ¬ν©λλ€!!