[Foundation -2] Monster 미니 프로젝트

sooyuni·2022년 6월 19일
0
post-thumbnail

과제 : Monster (State, Props, Effect Hook 사용 연습)

목표

  1. useEffect()훅을 통해 data fetching 등 컴포넌트 렌더링 이후에 필요한 다양한 side effect(부수효과) 일으키기
  2. fetch() 함수를 사용해 API 호출하는 방법 익히기.
  3. Array.map() 함수를 통해 component 재활용 해보기.
  4. props 를 사용해 단방향(부모 컴포넌트 > 자식 컴포넌트)으로 데이터를 전달해보기.
  5. Array.filter() 를 통한 검색기능을 구현해보기. (위의 필수 옵션 구현 후 추가 구현 사항!)
2주동안 배웠던 리액트 기초 개념을 적용하고 응용해서 Monster라는 과제를 진행했다.
오늘이 1차 프로젝트 진행 전 마지막 주말인데, 멘토님이 주말 동안 새로운 기능을 익히기 보다는
Monster 과제를 지웠다 다시 설치하면서 따라 치는거 없이 스스로 외워 칠 수 있을 때까지 반복하랬다. 
(최소 3번은 해보라고 했는데 지금 4번 정도 진행한 것 같다. 왜 다음날만 되면 늘 새로울까...?🤔) 

Task 1

  • directory 이동 후 해당 repo를 clone 받는다.
    (VSCode 터미널에서 git clone repo주소)
  • VSCode에서 해당 프로젝트 폴더를 연다.
  • VSCode 터미널을 열고 npm install

Task 2

  • API를 호출하기
    Monster.js 파일에서 아래의 키워드를 활용하여 API를 호출 한 후 state에 저장한다.
    useEffect fetch() useState()
  • useEffect는 Side Effect를 렌더링 이후에 발생시킨다.
    두 번째 인자가 하나도 없거나, 빈 배열이라면 아무런 일도 하지 않는다.
function Monsters() {
  const [monsters, setMonsters] = useState([]);

  // 데이터 로딩
  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then((res) => res.json())
      .then((data) => setMonsters(data));
  }, []);
  //이하 코드 생략

Task 3

  • API 호출의 결과값을 props를 사용하여 자식에게 전달한다.
  • CardList.js의 props에 콘솔을 찍어 데이터가 잘 넘어왔는지 확인한다.
    (확인 후에는 꼭 바로 지워줄 것!)
    Monsters.js
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));
  }, []);

  return (
    <div className="monsters">
      <h1>몬스터 미니 프로젝트!</h1>
      <CardList monsters={monsters} />
    </div>
  );
}

CardList.js

function CardList({ monsters }) {
  console.log(monsters)
  return (
    <div className="cardList">
    </div>
  );
}

↓콘솔 창에서 확인하면 아래와 같이 뜨는 것을 확인할 수 있다.

Task 4

  • Array.map( )사용
  • CardList.js 파일에서 넘겨 받은 데이터를 기준으로 map()함수를 사용하여 <Card/> 컴포넌트를 리턴해준다.
  • Card.js 에게 넘겨줘야하는 props 는 각 몬스터 객체의 id, name, email 이다.
function CardList({ monsters }) {
  return (
    <div className="cardList">
      {monsters.map((monster) => (
        <Card
          key={monster.id} //map함수를 쓸땐 고유의 key값을 부여할 것.
          id={monster.id}
          name={monster.name}
          email={monster.email}
        />
      ))}
    </div>
  );
}

Task 5

  • Card.js로 넘어가 넘겨받은 props를 이용하여 태그 안의 내용을 작성한다.

  • 이미지 주소의 경우 카드마다 다른 이미지를 보여줘야 하므로 주소의 숫자부분을 prop를 통해 넘겨받은 id로 대체해준다.

function Card({ id, name, email }) {
  return (
    <div className="cardContainer">
      <img
        src={`https://robohash.org/${숫자}?set=set2&size=180x180`}
        alt="monster"
      />
      <h2>{name}</h2>
      <p>{email}</p>
    </div>
  );
}

state와 props와 effect hook을 이용하여 아래와 같이 완성하였다.

Task 6 (Optional!)

  • 더 나아가 상단 가운데에 보이는 검색창filter() 메소드를 이용하여 Monster 검색 기능을 추가해보았다.

  • 먼저 <SearchBox/>props로 넘겨줄 handleChange 메소드를 정의한다.

function Monsters() {
  const [monsters, setMonsters] = useState([]);
  const [userInput, setUserInput] = useState("");

...중간 생략

  // SearchBox 에 props로 넘겨줄 handleChange 메소드 정의
  const findMonster = (e) => {
    const { value } = e.target;
    setUserInput(value);
  };
  
  return (
    <div className="monsters">
      <h1>몬스터 미니 프로젝트!</h1>
      <SearchBox handleChange={findMonster} />
      <CardList monsters={monsters} />
    </div>
  );
}
  • filter()메소드를 활용하여 필터링 로직을 구현한다.
    비교 대상은 monster 객체의 name값이며, 사용자가 소문자로 검색할 것을 고려하여
    소문자로 바꾼 monster 객체의 name값과 사용자가 검색 창에 입력한 userInput값을 비교한다.
  • filter()가 반환하는 값을 변수에 저장 후 return 문 안에 있는 CardList에 props로 전달한다.

Monsters.js

function Monsters() {
  const [monsters, setMonsters] = useState([]);
  const [userInput, setUserInput] = useState("");

  ...중간 생략

  // SearchBox 에 props로 넘겨줄 handleChange 메소드 정의
  const findMonster = (e) => {
    const { value } = e.target;
    setUserInput(value);
  };

  const monsterFilter = monsters.filter(
    (monster) =>
	monster.name.toLowerCase().includes(userInput.toLowerCase())
  );

  return (
    <div className="monsters">
      <h1>몬스터 미니 프로젝트!</h1>
      <SearchBox handleChange={findMonster} />
      <CardList monsters={monsterFilter} /> //기존의 monsters 대신 filter가 반환하는 값을 넘겨준다.
    </div>
  );
}

검색창에 d를 입력하면 이름에 d가 포함되어 있는 몬스터들만 필터링되어 보여준다.🤗🤗

profile
기록하고, 기록하자. 남는건 기록 뿐📝

0개의 댓글