React component 연습 | Monster 과제

Saemsol Yoo·2021년 2월 7일
0

React

목록 보기
6/6
post-thumbnail

✨ Task 1. API 호출

componentDidMount() fetch() setState()

🤚🏻 componentDidMount 란?
componentDidMount() is invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.

componentDidMount() {
   fetch("https://jsonplaceholder.typicode.com/users", {
     method: "GET",
   })
     .then((res) => res.json())
     .then((data) => {
       this.setState({
         monsters: data,
       });
     });
 }

1-1. componentDidMount()

데이터를 불러올 컴포넌트 파일(Monsters.js)에서, class 컴포넌트 안에 componentDidMount() 안에서 호출해준다.

1-2. fetch()

fetch 메소드를 이용해 호출할 API를 연결한다.

1-3. setState()

setState를 이용해 Monsters 클래스컴포넌트의 monsters 상태값을 변경시켜준다.

1-4. console.log()

👀 제대로 데이터가 호출되었는지 확인해보기위해 console.log(this.state.monsters) 를 찍어보면!

→ 데이터가 잘 호출되었다! 🥳 👏🏻



✨ Task 2. API 호출의 결과값 props로 자식에게 전달

props 활용

2-1. props

monsters.js (부모 컴포넌트)

 render() {
    console.log(this.state.monsters);
    return (
      <div className="Monsters">
        <h1>컴포넌트 재사용 연습!</h1>
        <CardList monsters={this.state.monsters} /> 
        //CardList 컴포넌트에게 monsters에 저장한 배열을 전달해준다.
      </div>
    );
  }

cardList.js (자식 컴포넌트)

class CardList extends Component {
  render() {
    console.log(this.props.monsters);  //props 객체로 전달받은 monsters 객체를 확인!
    return <div className="card-list"></div>;
  }
}

2-2. console.log()

👀 제대로 데이터가 CardList 컴포넌트로 전달되었는지 확인해보기위해 console.log(this.props.monsters) 를 찍어보면!

→ 자식컴포넌트에도 데이터가 잘 전달 되었다! 🥳 👏🏻



✨ Task 3. Array.map() 사용

Array.map()

✨ Card 컴포넌트에게 id , name, email 를 꼭 props 로 전달해줘야한다!

class CardList extends Component {
  render() {
    return (
      <div className="card-list">
        {this.props.monsters.map((monster) => {
          return (
            <Card
              key={monster.id}  //key값은 꼭! 🔥
              id={monster.id}
              name={monster.name}
              email={monster.email}
            />
          );
        })}
      </div>
    );
  }
}



✨ Task 4. props 활용

this.props.~

✨ CardList 컴포넌트로부터 전달받은 각각의 몬스터 정보 객체에서 id , name, email 활용해 card 컴포넌트를 완성해보자!

class Card extends Component {
  render() {
    const { id, name, email } = this.props;  //구조분해할당을 이용!
    return (
      <div className="card-container">
        <img
          src={`https://robohash.org/${id}?set=set2&size=180x180`}
          alt="monster card"
        />
        <h2>{name}</h2>
        <p>{email}</p>
      </div>
    );
  }
}



✨ Task 5. Array.filter() 를 이용한 검색기능

Array.filter()

Monsters.jsSearchBox 컴포넌트를 추가해주고, SearchBox 컴포넌트에 handleChange 메소드를 넘겨준다.

 state = {
    monsters: [],
    userInput: "",
  };

 handleSearch = (e) => {
    this.setState({ userInput: e.target.value });
 }

return (
      <div className="Monsters">
        <h1>컴포넌트 재사용 연습!</h1>
        <SearchBox handleChange={this.handleSearch} />
        <CardList monsters={filterMonsters} />
      </div>
    );

SearchBox 컴포넌트안에서 onChange 이벤트 발생시 props로 전달받은 handleChange 메소드를 호출한다.
→ 호출이 되면 다시 Monsters.js 에 있는 handleSearch 함수에 인자로 들어오는 이벤트객체(e)를 활용해 userInput 으로 setState 된다.

class SearchBox extends Component {
  render() {
    return (
      <input
        className="search"
        type="search"
        placeholder="Search..."
        onChange={this.props.handleChange}
      />
    );
  }
}

render() 안에서 filter를 이용해 검색이 되도록 하기!

여기서 비교 대상은 monster 객체의 name 값!
소문자로 바꾼 monster.name 값과 userInput값을 비교.
filter 메소드가 반환하는 값을 변수에 저장 후 return 문 안에 CardList에 props로 전달!

render() {
    const filterMonsters = this.state.monsters.filter((monsterCard) => {
      return monsterCard.name
        .toLowerCase()
        .includes(this.state.userInput.toLowerCase());
    });

    return (
      <div className="Monsters">
        <h1>컴포넌트 재사용 연습!</h1>
        <SearchBox handleChange={this.handleSearch} />
        <CardList monsters={filterMonsters} />
      </div>
    );
  }



Finish 🥳

profile
Becoming a front-end developer 🌱

0개의 댓글