기능
인풋에 입력받은 값을 추가하기 버튼을 누르면 왼쪽 TIL 리스트에 추가된다!
구현
- 제출용으로 App.js 하나에 보이도록 인라인으로 작성하였다.
- useRef 를 이용해서 선택하고 싶은 DOM에 ref 값을 설정 해서 해당 DOM 이 가리키는 .current 값을 받아와서 추가해줄 수 있도록 했다.
- 입력받은 값을 useState를 이용해서 배열에 넣어주어 상태관리를 해주었고, 이 배열 속에 있는 값을 map을 돌면서 화면에 붙여주도록 했다.
- 이 때 map을 사용할 경우 고유한 key 값을 주도록 메시지가 뜬다.
- 리액트 엘리먼트들은 누가 누구인지 알게 해주는 암묵적인 키 값을 가지고 있다. (기본적으로 랜덤으로 생성)
- 가상돔에서는 무언가가 변경되면 변경된 애들만 변경하려고 한다. 이 때 기본적으로 랜덤으로 키가 생성되는데, map 이나 filter 를 돌릴 때처럼 읽고 처리해야하는 구문의 경우 변한게 없을 수 있어도 마운트 될 때 마다 키 값이 달라지게되기 때문에 키 값이 달라지게 되면 결국 다시 재렌더링이 이루어지게 된다.
- 따라서 리액트에서는 map 과 같은 구문에서 고유 key값이 없을 때는 고유한 key 값을 넣도록 경고창을 띄운다.
App.js
import "./App.css";
import React from "react";
function App() {
const [tilList, setTilList] = React.useState([]);
const title_ref = React.useRef(null);
const content_ref = React.useRef(null);
const time_ref = React.useRef(null);
const addTIL = () => {
const tilData = {
title: title_ref.current.value,
content: content_ref.current.value,
time: time_ref.current.value,
};
setTilList([...tilList, tilData]);
};
return (
<div className="App">
<div
className="Container"
style={{
display: "flex",
justifyContent: "space-around",
margin: "20px",
}}
>
<div className="til-list" style={{ width: "60vmin" }}>
<h1>TIL</h1>
{tilList.map((til, idx) => {
return (
<div
className="til-item"
key={idx}
style={{
border: "1px solid #eee",
padding: "20px",
margin: "15px",
textAlign: "left",
}}
>
<b>{til.title}</b>
<p>{til.content}</p>
<p>{til.time}</p>
</div>
);
})}
</div>
<div
className="input-area"
style={{
display: "flex",
gap: "1rem",
flexDirection: "column",
}}
>
<div>
<span>과목</span>
<input ref={title_ref} />
</div>
<div>
<span>내용</span>
<input ref={content_ref} />
</div>
<div>
<span>공부시간</span>
<input ref={time_ref} />
</div>
<button
style={{
border: "none",
borderRadius: "4px",
padding: "10px",
background: "skyblue",
color: "#fff",
}}
onClick={addTIL}
>
추가하기
</button>
</div>
</div>
</div>
);
}
export default App;