React | 검색 기능 구현하기

dev_bomdong·2021년 8월 29일
2

React

목록 보기
4/8
post-thumbnail

React로 외부 API를 받아온 뒤, 검색창에 입력하면 관련 데이터가 나오는 기능을 구현해보았다.

참고로, 해당 사이트는 아래의 3단 구조 컴포넌트로 되어있다.
Monsters(최상위) > CardList > Card
아래엔 Monsters Class 코드 위주로, 또 import 부분 등은 생략하고 적어볼 예정

Step.1 : state 설정

  componentDidMount() {
    fetch("API주소")
      .then((res) => res.json())
      .then((data) => {
        this.setState({
          monsters: data,
          userInput: this.state.userInput,
        });
      });
  }

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

    this.setState({
      userInput: inputValue,
    });
  };

componentDidMount를 이용해 외부 API를 fetch함수로 불러와 그 데이터를 monsters의 value에 담고, userInput엔 state의 userInput값을 담는다.

검색창 input엔 onChange 이벤트를 주어서 변화가 생길 경우 state에 input값을 저장하는 함수 handleSearch가 실행되도록 했다.

Step. 2 : filter, includes 활용

이제 검색 기능의 핵심, filterincludes 활용 !
외부 API로 받은 데이터 배열 monsters의 값은 각각의 카드다. 따라서 배열의 값에 filter를 걸어서, name값에 input값을 포함하는 카드를 반환하는 배열 을 data 변수에 넣었다.

const data = this.state.monsters.filter(
  (card) => card.name.toLowerCase().includes(this.state.userInput));

Step. 3 : props 넘겨주기

필터링된 data를 newData라는 props로 CardList 컴포넌트에 넘겨주었다. 이제 CardList 컴포넌트에서 넘겨받은 newData를 잘 활용해 각각의 카드를 불러와주면 된다!

Monsters 컴포넌트 코드

  render() {
    const data = this.state.monsters.filter(
      (card) => card.name.toLowerCase().includes(this.state.userInput));
    return (
      <div className="Monsters">
        <h1>컴포넌트 재사용 연습!</h1>
        <SearchBox 
          handleChange={this.handleSearch} />
        <CardList newData={data} />
      </div>
    );
  }

CardList 컴포넌트 코드

class CardList extends Component {
  render() {
    return (
      <div className="card-list">
        {this.props.newData.map((card) => {
          return <Card key={card.id} id={card.id} name={card.name} email={card.email} />;
        })}
      </div>
    );
  }
}

로그인/회원가입 기능 만큼이나 자주 사용하게 될 검색기능
핵심인 filter, includes, map을 항상 기억하자!

profile
블로그 이사중입니다 https://dev-bomdong.tistory.com/

0개의 댓글