하루 하나씩 작성하는 TIL #20
https://www.notion.so/9fad483c66b04aff961879eaa1d4cd49?pvs=25#e88bff02edf049f4a4f6746f5ead2756
App.jsx만 주석에 따라 수정하면 되는 과제.
import { useState } from "react";
import "./App.css";
function App() {
const initialState = [
{ id: 1, name: "John", age: 20 },
{ id: 2, name: "Doe", age: 21 },
];
const [users, setUsers] = useState(initialState);
// 1. TODO: 이름과 나이를 각각 상태로 정의하세요. 초기값은 빈문자열("")입니다.
const addUser = (e) => {
e.preventDefault();
// 2. TODO: 이름과 나이가 모두 입력되지 않았을 때는 alert 처리하고 함수를 종료하세요. 논리합연산자 (||) 를 이용하세요.
// 3. TODO: 사용자 리스트 상태를 업데이트 하세요. spread operator 를 사용하고, 추가되는 id는 현재 시간을 밀리초 단위로 반환하는 Date.now() 를 사용하세요.
};
const removeUser = (id) => {
// 4. TODO: filter 메소드를 사용해서 사용자 삭제 로직을 구현해 보세요.
};
return (
<>
<h1>사용자 리스트</h1>
<form onSubmit={addUser}>
{/* 5. TODO: input 태그에 value, onChange 속성을 추가해서 이름과 나이의 상태와 상태변경 로직을 연결하세요 */}
<input type="text" placeholder="이름" />
<input type="number" placeholder="나이" />
<button type="submit">사용자 추가</button>
</form>
<ul>
{/* 6. TODO: map 메소드를 이용해서 user 리스트를 렌더링하세요. */}
{/* 7. 이름: John, 나이: 20 [삭제] 버튼이 하나의 행에 나올 수 있도록 해보세요. (hint: flex) */}
</ul>
</>
);
}
export default App;
const [name, setName] = useState("");
const [age, setAge] = useState("");
useState훅은 React에서 상태를 관리하기 위해 사용되는 함수이다.
첫 번째 값은 상태 값 자체이고, 두번째 값은 해당 상태 값을 변경하는 함수이다.
const addUser = (e) => {
e.preventDefault();
// TODO: 이름과 나이가 모두 입력되지 않았을 때는 alert 처리하고 함수를 종료하세요. 논리합연산자 (||) 를 이용하세요.
if (!name || !age) {
alert("이름과 나이를 모두 입력하세요.");
return;
}
폼이 제출될 때 기본 동작을 막아주는 이유는?
만약 사용자가 폼에서 '제출' 버튼을 클릭하면 이벤트가 트리거되고, 이벤트 객체 e에는 해당 이벤트에 대한 정보가 포함되는데, 이 경우에는 submit 이벤트에 대한 정보가 포함되어 있다.
e.preventDefault()를 호출함으로써, 폼의 제출과 관련된 페이지 새로고침(=이벤트 기본 동작)을 중단시킬 수 있습니다. 이렇게 하면 원래의 동작이 실행되지 않고, 개발자가 원하는 추가 동작(예: 폼 데이터의 유효성 검사, 데이터 전송 등)을 수행할 수 있다.
따라서 폼의 제출에 대한 기본 동작을 막아서 웹 페이지의 상태를 유지하고 사용자가 폼을 제출한 후에도 추가적인 작업을 수행할 수 있도록 한다.
// TODO: 사용자 리스트 상태를 업데이트 하세요. spread operator 를 사용하고, 추가되는 id는 현재 시간을 밀리초 단위로 반환하는 Date.now() 를 사용하세요.
setUsers([...users, { id: Date.now(), name, age }]);
// 입력 필드 초기화
setName("");
setAge("");
};
setUsers함수를 호출하여 기존 사용자 리스트 상태를 업데이트한다. spread 연산자를 사용하여 기존 사용자 리스트인 users를 새로운 배열로 복사한다. 이렇게 하면 기존 사용자 리스트의 모든 항목이 새로운 배열에 포함되게 된다 = 기존 사용자 리스트를 변경하지 않고 새로운 배열을 만든다
그리고 새로운 사용자 객체를 배열에 추가한다. 이 사용자 객체는 새로운 id, 사용자가 입력한 name, 그리고 age 값을 가지고 있는데, id는 현재 시간을 밀리초로 반환하는 Date.now() 함수를 사용하여 생성되며, 이를 통해 각 사용자 객체마다 고유한 식별자가 할당된다.
그리고 사용자가 새로운 데이터를 입력할 수 있도록 폼을 리셋해준다.
const removeUser = (id) => {
// TODO: filter 메소드를 사용해서 사용자 삭제 로직을 구현해 보세요.
setUsers(users.filter(user => user.id !== id));
};
id와 일치하지 않는 사용자를 제외한 나머지 사용자들을 포함하는 새로운 배열을 만들어서 사용자 리스트 상태를 업데이트 한다.
id가 주어진 id와 일치하지 않는 사용자들만을 선택한다.
필터 메서드를 통해 선택된 사용자들로 새로운 배열이 생성되었으므로,
이를 setUsers 함수의 인자로 전달하여 기존 사용자 리스트를 새로운 값으로 교체해준다.
{/* 5. TODO: input 태그에 value, onChange 속성을 추가해서 이름과 나이의 상태와 상태변경 로직을 연결하세요 */}
<input type="text" placeholder="이름" value={name} onChange={(e) => setName(e.target.value)} />
<input type="number" placeholder="나이" value={age} onChange={(e) => setAge(e.target.value)} />
<button type="submit">사용자 추가</button>
</form>
value는 입력 필드의 값으로, 상태 변수인 name, age를 사용한다. 이렇게 함으로써 입력 필드에 초기값을 설정하고, 이후에도 상태가 변경될 때 마다 필드 값이 업데이트 된다.
onChange 속성은 값이 변경될 때 발생하는 이벤트에 대한 핸들러를 지정한다. 입력 필드에 사용자가 어떤 값을 입력하면, 입력에 대한 처리를 수행한다.
화살표 함수를 이용하여 이벤트 핸들러를 정의해준다. e.target은 이벤트가 발생한 요소를 가리킨다.
e.target.value는 입력 필드에 사용자가 입력한 값이다.
setAge(e.target.value)는 입력 필드의 값이 변경될 때마다 호출되는 함수이다. e.target.value로부터 입력된 값을 가져와서, 이를 setAge 함수의 인자로 전달한다.
이렇게 함으로써 입력 필드의 값이 변경될 때마다 setAge 함수가 호출되어 age라는 상태 변수에 입력된 값이 업데이트된다.
{users.map(user => (
<li key={user.id} style={{ display: 'flex', alignItems: 'center' }}>
<span>이름: {user.name}, 나이: {user.age}</span>
<button onClick={() => removeUser(user.id)}>삭제</button>
</li>
))}
users 배열을 매핑하여 각 사용자에 대한 리스트 아이템을 생성해준다. map 함수는 배열의 각 요소에 대해 정의된 함수를 호출하고, 그 결과로 새로운 배열을 반환해준다.
key={user.id}는 React에서 동적으로 생성되는 리스트 아이템을 구분하기 위한 고유한 식별자이다. 여기서는 각 사용자의 id를 사용하여 고유한 키를 설정한다.
flex를 사용하여 수평 정렬 또한 해준다.
클릭 이벤트가 발생하면 removeUser 함수가 호출되고, 해당 사용자의 id가 전달된다.