Effect의 의존성 배열
에 객체
를 사용하면 생기는 문제점을 이해하고 내 코드를 수정해보자.
객체
, 배열
사용하면 생기는 문제점반응형 값으로 객체
, 배열
을 사용한 경우 변경된 값이 없어도 Effect가 실행될 수 있다.
import { useState, useEffect } from "react";
import { createConnection } from "./chat.js";
const serverUrl = "https://localhost:1234";
function ChatRoom({ roomId }) {
const [message, setMessage] = useState("");
const options = {
serverUrl: serverUrl,
roomId: roomId,
};
useEffect(() => {
const connection = createConnection(options);
connection.connect();
return () => connection.disconnect();
}, [options]);
return (
<>
<h1>Welcome to the {roomId} room!</h1>
<input value={message} onChange={(e) => setMessage(e.target.value)} />
</>
);
}
export default function App() {
const [roomId, setRoomId] = useState("general");
return (
<>
<label>
Choose the chat room:{" "}
<select value={roomId} onChange={(e) => setRoomId(e.target.value)}>
<option value="general">general</option>
<option value="travel">travel</option>
<option value="music">music</option>
</select>
</label>
<hr />
<ChatRoom roomId={roomId} />
</>
);
}
자바스크립트의 객체는 평가될 때마다 새로운 객체를 생성한다.
즉, 두 객체가 동일한 값을 가지로 있더라도 다른 메모리제 저장된 별개의 객체다.
var person1 = {
name: 'Lee'
};
var person2 = {
name: 'Lee'
};
console.log(person1 === person2); // false
별개의 객체라도 프로퍼티가 가리키는
원시값
을 비교 평가 할 수 있다.
// 프로퍼티 값을 참조하는 person1.name과 person2.name은 값으로 평가될 수 있는 표현식이다.
// 두 표현식 모두 원시 값 'Lee'로 평가된다.
console.log(person1.name === person2.name); // true
Effect 외부의 객체에서 비교할 원시값을 읽고 동일한 값
을 가진 객체인지 판단할 수 있다.
function ChatRoom({ options }) {
const [message, setMessage] = useState('');
const { roomId, serverUrl } = options;
useEffect(() => {
const connection = createConnection({
roomId: roomId,
serverUrl: serverUrl
});
connection.connect();
return () => connection.disconnect();
}, [roomId, serverUrl]); // ✅ All dependencies declared
// ...
useEffect(() => {
const postObjectToStore = { ...postObject };
localStorage.setItem('postObject', JSON.stringify(postObjectToStore));
console.log('변경사항 렌더링 체크');
}, [postObject]);
변경내용이 없는
postObject의 경우에도 Effect가 실행되고 있다.- postObject가 아닌 변경에도 Effect가 실행될 수 있다.
const { title, price, content, categoryId, locationId, files } = postObject;
useEffect(() => {
const postObjectToStore = {
title,
price,
content,
categoryId,
locationId,
files,
};
localStorage.setItem('postObject', JSON.stringify(postObjectToStore));
console.log('렌더링 체크');
}, [title, price, content, categoryId, locationId, files]);
객체의 원시값
을 읽어준다.원시값
을 비교한다.
- 동일한 값을 가진 객체인 경우 Effect가 일어나지 않는다.
자바스크립트 객체의 특성을 알고 있고 자바스크립트로 구현할때는 조심하려고 신경 썻던 부분을 리액트에서는 안일하게 생각하고 있었던 것 같다. 그래서 더욱 글로 남겨두고 싶었다. 리액트는 자바스크립트의 특징과 문법을 활용한 점을 잊지말자.