위코드 파운데이션 과정을 들으며 정리한 내용입니다.
바탕화면으로 이동한 후 깃 클론으로 프로젝트 파일을 받고, 기록된 패키지들을 설치합니다.
git clone [레파지토리 주소]
- 프로젝트 파일 내려받기
npm install
- pakage.json 에 기록된 패키지들 설치
npm start
- 파일 동작 확인
데이터 로딩은 첫 렌더링 때 한번만 실행되도록 useEffect 를 사용하고, 의존성 배열을 비워둡니다.
useEffect(() => {
fetch( 'api 주소', {
method: 'GET'
})
}, [])
이때 method: 'GET' 은 생략 가능하고 응답값을 콘솔로 찍어볼 수 있습니다.
useEffect(() => {
fetch( 'api 주소' )
.then(( res ) => console.log(res))
}, [])
응답이 확인 되면, json 데이터를 js 로 변환하고 들어온 데이터를 State 에 저장합니다.
useEffect(() => {
fetch( 'api 주소' ) // 데이터 가져와서
.then(( res ) => res.json()) // json 데이터를 js 로 변경하고
.then(( result ) => setMonsters(result)) // 위에 선언한 state 에 저장
}, [])
최상단에 아래와 같은 State 가 선언된 상태
const [monsters, setMonsters] = useState([]);
자식 컴포넌트에게 Props 방식으로 데이터를 전달하고
<CardList monsters={monsters} />
자식 컴포넌트는 Props 를 받습니다. 우선 데이터가 받아지는지 콘솔을 찍어 확인합니다.
function CardList(monsters) {
console.log(monsters);
return ();
}
이제 CardList 컴포넌트가 받은 Props 데이터로 map 메서드를 돌려 Card 컴포넌트를 생성합니다. (데이터 수 만큼) Props 데이터는 구조분해할당으로 객체 형태로 받습니다.
function CardList({ monsters }) {
return (
<div className="cardList">
{monsters.map((monster)=>{
return (
<Card
// 객체의 key 값으로, value 에 해당하는 값 전달
key={monster.id}
id={monster.id}
name={monster.name}
email={monster.email}
/>
);
})}
</div>
);
}
이제 Card 컴포넌트가 데이터를 받아서 해당 카드 이미지를 그려줍니다. 구조분해할당으로 id, name, email 에 해당하는 value 값을 바로 사용합니다. 이미지 주소는 중간 숫자만 1, 2, 3.. 순으로 바꾸는 것이므로,(id 값으로 넣어줌) 백틱을 활용한 템플릿 리터럴과 달러를 활용해서 넣어줍니다.
function Card({ id, name, email }) {
return (
<div className="cardContainer">
<img src={`이미지주소${숫자}이미주소`} alt="" />
<h2>{name}</h2>
<p>{email}</p>
</div>
);
}
서치박스에 입력하는 값과 monster 객채의 name 값을 비교해서 filter 메서드가 반환하는 새로운 배열의 값을 CardList 컴포넌트에 전달합니다. 서치박스가 아래와 같이 onChange 속성으로 Props 데이터를 받을 때,
function SearchBox(props) {
return (
<input
className="search"
type="search"
placeholder="Search..."
onChange={props.handleChange} // 입력 값 받기 위해서
/>
);
}
부모 컴포넌트에서 전달하는 함수를 만들어 줍니다.
// 이렇게 프롭스를 전달한다고 할 때
<SearchBox handleChange={updateUserInput} />
// 최상단에 이렇게 state 가 선언되어 있다면
const [userInput, setUserInput] = useState("");
// updateUserInput 함수를 작성하면
const updateUserInput = (e) => {
setUserInput(e.target.value);
}
userInput 이란 state 에 유저가 입력하는 값을 저장했다면 이 값과 기존 monster 의 name 을 비교해서 일치하는 것이 있을 때 반환하는 필터링을 진행합니다.
const sortedMonsters = monsters.filter((monster)=>{
return monster.name.includes(userInput);
});
filter 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열을 반환합니다. 이때 입력하는 값과 기존 몬스터 이름의 대소문자가 다르면 인식을 못하기 때문에 소문자로 변환하는 toLowerCase() 메서드를 사용합니다.
const sortedMonsters = monsters.filter((monster)=>{
return monster.name.toLowerCase().includes(userInput.toLowerCase());
});
이제 필터링 된 sortedMonsters 데이터를 CardList 에게 전달합니다. 그럼 화면에는 검색에 기반해 일치하는 카드만 보여지게 됩니다.
<CardList monsters={sortedMonsters} />