React 개념 이해 확인을 위한 Mini Test 결과 분석
function App() {
const students = [
{ name: "Alice", age: 17, grade: "A" },
{ name: "Bob", age: 18, grade: "B" },
{ name: "Charlie", age: 16, grade: "C" },
{ name: "Diana", age: 19, grade: "D" },
];
const filteredStudents = students.filter((student) => student.age >= 18);
return (
<div>
<h1>학생 목록</h1>
<ul>
{filteredStudents.map((student, index) => (
<li key={index}>
<button
onClick={() => {
alert(`${student.name} - 나이: ${student.age} / 점수: ${student.grade}`);
}}
>
{student.name}
</button>
</li>
))}
</ul>
</div>
);
}
export default App;
function App() {
// 생략
const printAgeAndGrade = () => {
alert(`${student.name} - 나이: ${student.age} / 점수: ${student.grade}`);
};
return (
// 생략
<ul>
{filteredStudents.map((student) => {
<li>
<button onClick={printAgeAndGrade}>
{student.name}
</button>
</li>
})}
</ul>
);
}
map() 메서드를 사용하는 경우, 각 요소에 빠르게 접근하기 위해 요소의 id를 key로 지정해야 한다.
만일, id가 지정되어있지 않은 경우, 콜백함수의 index를 최후의 수단으로 활용한다.
return (
// 생략
<ul>
{filteredStudents.map((student, index) => {
<li key={index}>
// 생략
</li>
})}
</ul>
);
import { useState } from "react";
function App() {
const students = [
{ name: "Alice", age: 17, grade: "A" },
{ name: "Bob", age: 18, grade: "B" },
{ name: "Charlie", age: 16, grade: "C" },
{ name: "Diana", age: 19, grade: "D" },
{ name: "Elmo", age: 20, grade: "E" },
{ name: "Fiona", age: 21, grade: "F" },
{ name: "Gabe", age: 22, grade: "A" },
{ name: "Hannah", age: 23, grade: "B" },
{ name: "Irene", age: 24, grade: "C" },
{ name: "Jenny", age: 25, grade: "D" },
{ name: "Kevin", age: 26, grade: "E" },
{ name: "Linda", age: 27, grade: "F" },
];
const [minAge, setMinAge] = useState(18);
const filteredStudents = students.filter((student) => student.age >= minAge);
const studentList = filteredStudents.map((student, index) => (
<li key={index}>
{student.name} - Age: {student.age}, Grade: {student.grade}
</li>
));
const ageChangeHandler = (e) => {
setMinAge(e.target.value);
};
return (
<div>
<h1>학생 목록</h1>
다음 나이 이상의 학생목록만 출력해요 :{" "}
<input type="number" value={minAge} onChange={ageChangeHandler} /> 살 이상
<ul>{studentList}</ul>
</div>
);
}
export default App;
function App() {
// 생략
const ageChangeHandler = (e) => {
setMinAge(e.target.value);
};
return (
// 생략
<input type="number" onChange={ageChangeHandler} />
);
}
작동에는 이상이 없으나, 올바른 코드는 아니다.
이유
: <input>
의 value가 state
임을 명시적으로 선언하지 않아 <input>
에 대한 제어권을 가지고 있지 않음
: 따라서, 외부에서 해당 value가 변경될 있음
해결 방법
: <input>
의 value를 선언한다. <input value={variable} />
기억해야 할 부분
:<input>
에서 Handler를 사용하는 경우, 반드시value
를 선언한다.
import { useState } from "react";
function App() {
const [students, setStudents] = useState([
{ name: "Alice", age: 17, grade: "A" },
{ name: "Bob", age: 18, grade: "B" },
{ name: "Charlie", age: 16, grade: "C" },
{ name: "Diana", age: 19, grade: "D" },
{ name: "Elmo", age: 20, grade: "E" },
{ name: "Fiona", age: 21, grade: "F" },
{ name: "Gabe", age: 22, grade: "A" },
{ name: "Hannah", age: 23, grade: "B" },
{ name: "Irene", age: 24, grade: "C" },
{ name: "Jenny", age: 25, grade: "D" },
{ name: "Kevin", age: 26, grade: "E" },
{ name: "Linda", age: 27, grade: "F" },
]);
const [filteredStudents, setFilteredStudents] = useState(students);
const filterByAge = (minAge) => {
const studentsFilteredByAge = students.filter((student) => student.age >= minAge);
setFilteredStudents(studentsFilteredByAge);
};
const filterByGrade = (grade) => {
const studentsFilteredByGrade = students.filter((student) => student.grade === grade);
setFilteredStudents(studentsFilteredByGrade);
};
const resetFilter = () => {
setFilteredStudents(students);
};
return (
<div>
<h1>학생 목록</h1>
<button onClick={() => filterByAge(24)}>24세 이상</button>
<button onClick={() => filterByGrade("A")}>A등급</button>
<button onClick={resetFilter}>필터 초기화</button>
<ul>
{filteredStudents.map((student, index) => (
<li key={index}>
{student.name} - Age: {student.age}, Grade: {student.grade}
</li>
))}
</ul>
</div>
);
}
export default App;
// App.jsx
import { useState } from "react";
import FilterButtons from "./components/FilterButtons";
import StudentList from "./components/StudentList";
function App() {
const initialStudents = [
{ name: "Alice", age: 17, grade: "A" },
{ name: "Bob", age: 18, grade: "B" },
{ name: "Charlie", age: 16, grade: "C" },
{ name: "Diana", age: 19, grade: "D" },
];
const [filteredStudents, setFilteredStudents] = useState(initialStudents);
return (
<div>
<h1>학생 목록</h1>
<FilterButtons initialStudents={initialStudents} setFilteredStudents={setFilteredStudents} />
<StudentList filteredStudents={filteredStudents} />
</div>
);
}
export default App;
// FilterButtons.jsx
function FilterButtons({ initialStudents, setFilteredStudents }) {
const filterByAge = (minAge) => {
const studentsFilteredByAge = initialStudents.filter((student) => student.age >= minAge);
setFilteredStudents(studentsFilteredByAge);
};
const filterByGrade = (grade) => {
const studentsFilteredByGrade = initialStudents.filter((student) => student.grade === grade);
setFilteredStudents(studentsFilteredByGrade);
};
const resetFilter = () => {
setFilteredStudents(initialStudents);
};
return (
<div>
<button onClick={() => filterByAge(18)}>18세 이상</button>
<button onClick={() => filterByGrade("A")}>A등급</button>
<button onClick={resetFilter}>필터 초기화</button>
</div>
);
}
export default FilterButtons;
// StudentList.jsx
function StudentList({ filteredStudents }) {
return (
<ul>
{filteredStudents.map((student, index) => (
<li key={index}>
{student.name} ({student.age})세 - {student.grade}등급
</li>
))}
</ul>
);
}
export default StudentList;
// FilterButtons.jsx
function FilterButtons(...) {
// 생략
return (
<div>
<button onClick={filterByAge}>18세 이상</button>
<button onClick={filterByGrade}>A등급</button>
// 생략
</div>
);
}
입력값이 존재하는 함수 리터럴을 잘못 호출하였다.
기억해야 할 부분
1. 입력값이 존재하는 함수 리터럴은 호출할 때도 입력값을 담아서 호출해야 한다.
2.함수명(입력값)
만 입력하는 경우, 함수가 바로 실행되기 때문에, 앞에() =>
를 작성해야 한다.<button onClick={() => filterByAge(18)>18세 이상</button> <butotn onclick={() => filterByGrade("A")}>A등급</button>