Task 1. API 호출
- 파일: Monsters.js
- 아래 키워드들을 활용해 데이터를 호출 한 후, state에 저장 해주세요!
- useEffect()
- fetch() → 호출할 API 주소:
https://jsonplaceholder.typicode.com/users- useState() → useState 훅을 이용해 state에 데이터를 저장1
Task 2. API 호출의 결과값 props 로 자식에게 전달
- 파일: Monsters.js
- 데이터를 저장한 state를 자식 컴포넌트인 에 넘겨주세요. (props 활용)
- 넘겨준 후 CardList.js 에서 props 를 콘솔에 찍어 확인해주세요. (개발 단계에서 확인하는 용도이니 확인 완료 후에는 콘솔을 지워주세요!)
Task 3. Array.map( ) 사용
- 파일: CardList.js
- 🚨 Array.map() 함수 사용법을 꼭 익히고 시작해주세요!
- 넘겨 받은 데이터를 기준으로 Array.map() 함수를 활용하여 컴포넌트를 리턴해주세요.
- Card.js 에게 넘겨줘야하는 props 는 각 몬스터 객체의 id, name, email 입니다.
Task 4. props 활용
- 파일: Card.js
- Card.js 컴포넌트 모양 및 구조
<div className="card-container"> <img src=이미지주소 alt="monster" /> <h2>Name</h2> <p>Email</p> </div>
- 이미지 주소 (src)
https://robohash.org/숫자?set=set2&size=180x180 카드마다 다른 이미지를 보여주기 위해 위 주소의 숫자 부분을 props 로 내려받은 id 로 대체해주세요.
예시)
https://robohash.org/1?set=set2&size=180x180
https://robohash.org/2?set=set2&size=180x180
https://robohash.org/3?set=set2&size=180x180
monster.js
import React, { useEffect, useState } from "react";
import SearchBox from "./Components/SearchBox/SearchBox";
import CardList from "./Components/CardList/CardList";
import "./Monsters.scss";
/**********************************************************
API 주소: https://jsonplaceholder.typicode.com/users
1. 위 주소를 호출하여 데이터 로딩을 처리해주세요!
- useEffect()
- fetch
- setState (monsters 에 저장)
2. SearchBox 컴포넌트에 정의한 handleChange 메소드를 넘겨주고,
호출 시 인자로 들어오는 이벤트객체(e)를 활용해 userInput 으로 setState.
3. 필터링 로직 구현 (filter 메소드 활용)
여기서 비교 대상은 monster 객체의 name 값입니다.
소문자로 바꾼 monster.name 값과 userInput값을 비교.
filter 메소드가 반환하는 값을 변수에 저장 후 return 문 안에 CardList에 props로 전달
***********************************************************/
function Monsters() {
const [monsters, setMonsters] = useState([]);
const [userInput, setUserInput] = useState("");
// 데이터 로딩
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((res) => res.json())
.then((data) => {
setMonsters(data);
});
}, []);
// SearchBox 에 props로 넘겨줄 handleChange 메소드 정의
const updateUserInput = (e) => {
setUserInput(e.target.value);
};
const sortedMonsters = monsters.filter((monster) => {
return monster.name.toLowerCase().includes(userInput.toLowerCase());
});
return (
<div className="monsters">
<h1>컴포넌트 재사용 연습!</h1>
{<SearchBox handleChange={updateUserInput} />}
{<CardList monsters={sortedMonsters} />}
</div>
);
}
export default Monsters;
CardList.js
import React from "react";
import Monsters from "../../Monsters";
import Card from "../Card/Card";
import "./CardList.scss";
/***********************************************************
Card 컴포넌트를 import 한 뒤, props로 내려받은 데이터에
map 함수를 호출해 각각 다른 데이터를 가진 Card 컴포넌트들을 리턴해주세요!
Card 컴포넌트에서 필요로 하는 데이터는 id, name, email 입니다.
***********************************************************/
function CardList({ monsters }) {
return (
<div className="cardList">
{monsters.map((monster) => {
return (
<Card
key={monster.id}
id={monster.id}
name={monster.name}
email={monster.email}
/>
);
})}
</div>
);
}
export default CardList;
Card.js
import React from "react";
import "./Card.scss";
/***********************************************************
Card 컴포넌트 구조
<img src=이미지주소 alt="">
<h2>Name</h2>
<p>Email</p>
Card 컴포넌트에서 props로 받아야하는 데이터는 id, name, email 입니다.
props에서 해당하는 키값들을 추출하여 위와 같은 구조로 만들어주세요!
이미지주소: `https://robohash.org/${숫자}?set=set2&size=180x180`
카드마다 다른 이미지를 보여주기 위해
위 주소의 숫자 부분을 props로 내려받은 id로 대체하셔야 합니다.
Name 과 Email 도 마찬가지입니다.
***********************************************************/
function Card({ id, name, email }) {
return (
<div className="cardContainer">
<img
src={`https://robohash.org/${id}?set=set2&size=180x180`}
alt="monster"
/>
<h2>{name}</h2>
<p>{email}</p>
</div>
);
}
export default Card;
SearchBox.js
import React from "react";
import "./SearchBox.scss";
function SearchBox(props) {
return (
<input
className="search"
type="search"
placeholder="Search..."
onChange={props.handleChange}
/>
);
}
export default SearchBox;