react에서는 배열에 대해 useState가 동작하지 않는다?
react에서 아래와 같이 messages라는, 배열을 갖는 state를 변경하려고 시도하면 변경된 값이 반영안되는 것을 확인할 수 있습니다.
이럴 때는, spread 문법을 사용해서 상태값을 변경해주면 됩니다.
import React, { useState } from 'react';
export default function Chat(props) {
let [messages, setMessages] = useState(['test1', 'test2']);
function change(){
messages.push("test");
setMessages(messages);
}
return (
<div>
{
items.map((item, index) =>{
return (
<div key={index}>{item}</div>
)
}
}
</div>
)
}
해결방법
앞선 문제가 발생했을 때, setState를 할 때, 아래와 같이 spread syntax를 사용해주면 됩니다.
let messages_new = [...messages, "test"];
setMessages(messages_new);
spread 문법 (...message)
아래와 같이 변수명 앞에 ... 이 붙는것을 spread syntax라고 합니다.
[...messages, "test"]
스프레드 구문, 전개 구문이라고도 부릅니다.
스프레드(...) 구문은 대상을 개별 요소로 분리합니다.
Spread 문법의 대상은 iterable(반복가능)이어야 합니다.
spread 구문에 대한 실행예제는 아래와 같습니다.
// ...[1, 2, 3]는 [1, 2, 3]을 개별 요소로 분리한다(→ 1, 2, 3)
console.log(...[1, 2, 3]) // 1, 2, 3
// 문자열은 반복가능.
console.log(...'Hello'); // H e l l o
// 이터러블이 아닌 일반 객체는 Spread 문법의 대상이 될 수 없다.
console.log(...{ a: 1, b: 2 });
let messages_new = [...messages, "test"];의 의미
[...messages, "test"] 는 messages에 있는 배열요소들을 나누어,
새로운 배열에 각 요소들을 넣는다는 뜻입니다.
즉, messages = ['test1', 'test2']이므로,
let messages_new = ['test1', 'test2', "test"] 가 되는 것입니다.
useState가 동작하지 않는 이유
setState는 이전 상태와 값을 비교하여 값이 다를 경우에 DOM을 다시 redering을 해줍니다.
그런데 만일 아래와 같이 쓴다면,
setMessages에 전달할 messages의 값이 이미 바뀌어져서
동일해지기 때문에 DOM을 다시 redering하지 않습니다.
messages.push("test");
// setMessage를 call 하기 직전에,
// messages의 이전상태는 : ["test1", "test2" ,"test"]
// messages에 변경할 상태는 : ["test1", "test2" ,"test"]
setMessages(messages);
따라서 이전 상태와 변경할 상태를 다르게 하기 위해,
새로 배열을 만들어서(copy) 변경을 가한다음에 setMessages를 호출하도록 합니다.
javascript,react,reactjs
'자바스크립트 - Javascript' 카테고리의 다른 글
vue3 빌드하지않고 사용하기 (0) | 2024.09.20 |
---|---|
vue3 lifecycle hook, vue3 라이프사이클 순서, vue3 onMounted/unmounted/beforecreate, vue3 라이프사이클 예제코드 (3) | 2024.09.16 |
vue3 router 사용법, vue router params, vue router push, vue router history, vue dynamic route (1) | 2024.09.04 |
vue3 watch 사용법, vue3 watch 여러개, vue3 watchEffect 사용법 (0) | 2024.08.20 |
vue3 slot이란, vuejs slot 사용법, vue slot 여러개, v-slot (0) | 2024.08.18 |
댓글