[React] 과제 몬스터#컴포넌트 재사용 및 필터검색

최송희·2021년 3월 14일
1

React

목록 보기
2/4

2주 전 리액트를 처음 접하게되었다.
하...위코드 들어오기전에 리액트 조금이라도 공부해올껄! 하는 후회가 계속되었지만 늦은 후회일뿐! 그래도 2주를 헤매이다보니 어느 순간 리액트로 뭔간 만들고있다

리액트 기초를 마무리하며 Monster들을 뿌려주는 작은 웹사이트를 제작해본다.

Task 1. API 호출

  • 파일: Monsters.js
  • 아래 키워드들을 활용해 데이터 로딩을 처리해주세요!
    1. componentDidMount()
    2. fetch()호출할 API 주소: https://jsonplaceholder.typicode.com/users
    3. setState() → state 객체 내에 monsters 라는 key 값에 저장
class Monsters extends Component {
  state = {
    monsters: [],
  };

  // 데이터 로딩
  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then((res) => res.json())
      .then((data) => {
        this.setState({
          monsters: data,
        });
      });
  }

  // SearchBox 에 props로 넘겨줄 handleChange 메소드 정의

  render() {
    );
    return (
      <div className="Monsters">
        <h1>컴포넌트 재사용 연습!</h1>
        {<SearchBox />}
        {<CardList />}
      </div>
    );
  }
}
  • componentDidMount()
    react 기본함수이며 render 실행 후 초기 1번만 실행되는 함수이다. 초기 데이터를 불러올때 사용한다.

  • fetch("API주소", {method: 'GET'})
    fetch 함수를 이용해서 데이터를 받아 올 수있다. method:'GET'은 default 값이라 생략 가능

  • fetch를 통해 받아온 데이터는 string 형태이다. json()파일로 형변환을 한 뒤 state값에 담아 활용하자. (반대로 서버에 js에서 데이터를 넘길때(method : 'POST') 는 stringify로 문자열로 변환하여 전달한다)

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

  • 파일: Monsters.js
  • API 호출 후 저장한 배열을 자식 컴포넌트인 <CardList /> 에 넘겨주세요. (props 활용)
  • 넘겨준 후 CardList.js 에서 props 를 콘솔에 찍어 확인해주세요.
    (개발 단계에서 확인하는 용도이니 확인 완료 후 push 하기 전에는 지워주세요!)
// Monster.js
  render() {
    );
    return (
      <div className="Monsters">
        <h1>컴포넌트 재사용 연습!</h1>
        {<SearchBox />}
        {<CardList monsters={this.state.monsters} />}
      </div>
    );
  }
}

//CardList.js
  render() {
    const { monsters } = this.props;
    console.log("CardList props : ", monsters);
    return (
      <div className="card-list"/>
    );
  }
  • props를 자식에게 넘긴 뒤 자식컴포넌트에서 render함수 내 console.log(this.props)를 통해 잘 넘어왔는지 확인한다.

Task 3. Array.map( ) 사용

  • 파일: CardList.js
  • 🚨 Array.map() 함수 사용법을 꼭 익히고 시작해주세요!
  • 넘겨받은 배열을 기준으로 Array.map() 함수를 활용하여 <Card /> 컴포넌트를 리턴해주세요.
  • Card.js 에게 넘겨줘야하는 props 는 각 몬스터 객체의 id, name, email 입니다.
render() {
    const { monsters } = this.props;
    console.log("CardList props : ", monsters);
    return (
      <div className="card-list">
        {monsters.map((card) => {
          return (
            <Card
              key={card.id}
              name={card.name}
              email={card.email}
              id={card.id}
            />
          );
        })}
      </div>
    );
  }
  • map() 함수
    arr.map(callback(currentValue[, index]))
    배열 내의 모든 요소 각각에 함수를 적용해 새로운 배열로 반환한다.
    여기서는 monsters 배열을 하나씩 돌면서 Card 컴포넌트를 그려준다. 그리고 Card컴포넌트에 monsters 배열 내 각각의 정보를 넘겨준다.

Task 4. props 활용


  render() {
    console.log("Card props : ", this.props);
    return (
      <div className="card-container">
        <img
          src={`https://robohash.org/${this.props.id}?set=set2&size=180x180`}
          alt="profileImage"
        />
        <h2>{this.props.name}</h2>
        <p>{this.props.email}</p>
      </div>
    );
  }
  • 부모 컴포넌트로 전달받은 props를 활용하는 것은 동일지만, 이미지 주소에 state을 활용하면서 동적인 url을 만들어 이미지를 세팅한다.

Optional. filter 활용

  • 상단의 검색창 입력 단어로 몬스터들의 이름을 조회한다.
  • 파일: SearchBox.js, Monsters.js
//SearchBox.js
  render() {
    return (
      <input
        className="search"
        type="search"
        placeholder="Search..."
        onChange={this.props.handleChange}
      />
    );
  }

//Monster.js
handleChange = (e) => {
  this.setState({
    userInput: e.target.value,
  });
};

// SearchBox 에 props로 넘겨줄 handleChange 메소드 정의

render() {
  // console.log("userInput : ", this.state.userInput, this.state.monsters);
  const monstersFiltered = this.state.monsters.filter((monster) =>
    monster.name.toLowerCase().includes(this.state.userInput.toLowerCase())
  );
  // monstersFiltered.filter()
  return (
    <div className="Monsters">
      <h1>컴포넌트 재사용 연습!</h1>
      {<SearchBox handleChange={this.handleChange} />}
      {<CardList monsters={monstersFiltered} />}
    </div>
  );
}
  • 함수도 props로 전달이 가능하다!
    1) 자식 컴포넌트 (SearchBox.js) 내 input의 값이 변경 될 때마다 부모함수를 호출한다.
    2) 부모함수에 선언되있는 함수는 자식에게서 event 객체를 매개변수로 받는다.
    3) event 객체를 통해 입력된 값을 전달받고, state 변수에 저장한다.
    4) render 함수 내에서 저장된 state 정보를 기준으로 filter 건 뒤 다른 자식컴포넌트 (CardList)에 전달한다.

  • filter() 함수
    map과 사용방식(?) 이 비슷하다.
    filter는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.
    예) monsters.filter(monster=> monster.name.includes("몬스터이름")

느낀 점
리액트 참 매력적이다! 재사용 가능한 UI단위를 일컫는 컴포넌트가 매력의 핵심!
아직은 미숙하지만 라이트하게 리액트 기본을 익혔으니 본격 플젝도 한번 가보즈아~

1개의 댓글

comment-user-thumbnail
2021년 3월 14일

플젝 가즈아🔥 송희님 파이팅!

답글 달기