인스타그램 클론코딩을 진행해보면서 하나의 피드 Component를 만들었던 것을 가지고 데이터를 통해 map을 활용하여 여러개의 피드를 찍은것을 보며 React의 장점을 다시금 알게 되었다. 오늘은 Monsters라는 과제를 하면서 Component재사용과 Props의 활용등을 다시 공부하게 되었다.
Monsters.js > CardList.js > Card.js
그러면 이러한 형태의 데이터가 State에 담기게 되고, 이 데이터를 활용하여 컴포넌트 UI들을 화면에 보여줘야 되니 이를 Props로 전달해주었다.
CardList에서는 전달받은 데이터의 개수만큼, 위에 사진에서는 총 10개의 데이터를 전달받았으니 10번의 map을 돌아 총 10개의 UI를 찍을 수 있게 된다.
function Card(props) {
return (
<div className="card-container">
<img
src={`https://robohash.org/${props.id}?set=set2&size=180x180`}
alt="monster"
/>
<h2>{props.name}</h2>
<p>{props.email}</p>
</div>
);
}
따라서, 이 한개의 Component를 만듦으로써 각각의 사진, 이름, email정보를 가진 UI들을 데이터의 개수만큼 찍어낼 수 있다.
그렇다면 이러한 방식으로 찍어낸 UI들을 검색하고 싶다면 어떻게 해야될까. 처음에는 input에 onChange를 사용하여 e.target.value를 state를 담고 이를 활용하여 filter를 사용하면 되겠다라고 생각했었는데, 생각해보니 보통 검색창에서는 입력값에 실시간으로 UI가 그려지는 것이 아닌 검색버튼을 눌렀을때 실행이 되니 onClick이벤트과 state를 적절히 잘 활용해야겠다는 생각이 들었다.
function Monsters() {
const [monsters, setMonsters] = useState([]);
const [search, setSearch] = useState("");
const [callbackSearch, setcallbackSearch] = useState("");
useEffect(() => {
fetch(`https://jsonplaceholder.typicode.com/users`)
.then((response) => response.json())
.then((json) => setMonsters(json));
}, []);
return (
<div className="monsters">
<h1>컴포넌트 재사용 연습!</h1>
<input
value={search}
placeholder="몬스터찾기"
type="text"
onChange={(e) => {
setSearch(e.target.value);
}}
/>
<button
onClick={() => {
setcallbackSearch(search);
}}
> 검색
</button>
<CardList monsters={monsters} search={callbackSearch} />
</div>
);
}
우선 filter를 사용하려면 input창에서 일어나는 value를 알아야 하니, search라는 state에서 실시간으로 입력되는 e.target.value를 담아주었다.
처음에는 실시간으로 input의 value를 담은 search state를 바로 CardList.js에게 Props로 전달해주려고 했지만, 실시간으로 UI가 변하는 것을 보고,
callbackSearch라는 state를 만들어 버튼에서 onClick이벤트가 일어나면 callbackSearch의 state값으로 search를 담아주고, 이를 Props로 전달해주었다.
function CardList(props) {
return (
<div className="cardList">
{props.monsters
.filter((monster) => monster.name.includes(props.search))
.map((monster) => (
<Card id={monster.id} name={monster.name} email={monster.email} />
))}
</div>
);
}
먼저, 내가 입력값을 onClick이벤트가 일어나면 Props로 전달해주었으니, CardList.js에는 위와 같이 "C"라는 키워드를 검색하면 이 키워드도 데이터와 함께 전달받게 된다. 이를 활용하여 먼저 데이터에서 filter를 활용해 search state에 담긴 값을 포함하고 있는 새로운 배열을 반환하고, 그 데이터를 가지고 Card라는 Component에게 id, name, email를 Props로 전달하고 map을 돌리게 된다.
input에 value를 search state로 지정한 이유
<button onClick={() => {
setSearch("");
}}
>
검색창 초기화
</button>
input창의 value를 내가 원하는대로 만질 수 있다.