TIL 28 | React - toy project

Soojeong Lee·2021년 7월 4일
0

react

목록 보기
7/7
post-thumbnail

React - toy project

리액트를 알게된 지 2주, 좌충우돌 리액트 적응기 !
🎯 목표 : React 관련 주어진 키워드를 활용해 자료를 찾아보면서 적용하기
❗️ 코드 스포 주의 ❗️

What I Learn

  1. componentDidMount() 메소드를 통해 라이프 사이클에 대한 이해를 높인다.
  2. fetch() 함수를 사용해 API 호출을 할 수 있다.
  3. Array.map() 함수를 통해 component를 재활용할 수 있다.
  4. props 를 사용해 단방향(부모 컴포넌트 -> 자식 컴포넌트)으로 데이터를 전달할 수 있다.
  5. Array.filter() 를 통한 검색기능을 구현할 수 있다.

Directions & Solutions

Task 1. API 호출

  • 아래 키워드들을 활용해 데이터 로딩을 처리해주세요!
    1. componentDidMount()
    2. fetch()호출할 API 주소 입력
    3. setState() → state 객체 내에 monsters 라는 key 값에 저장

✏️ 키워드 이해하기
1. componentDidMount()
React 컴포넌트의 life cycle을 살펴보면, render 후 componentDidMount()가 호출 된다. 따라서 화면에 가장 처음 그려져야하는 state 값들을 넣어주면 된다.

  1. fetch()
    fetch()함수를 통해 받아온 데이터를 받아 올 것이다. () 안에fetch할 데이터가 있는 API 주소를 불려오면 된다.

  2. setState() → state 객체 내에 monsters 라는 key 값에 저장
    setState()는 state를 업데이트 하는 함수이다. 즉, monsters라는 key값의 state인 빈 배열[]에 받아온 데이터를 저장해주면 된다.
// Monsters.js
// 데이터 로딩
  componentDidMount() { // task1 - mission1
    fetch('API 주소') //task1 - mission2
    .then(res => res.json())
    .then(data => {
      this.setState({ //  task1 - mission3
        monsters : data
      })
    })

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

  • API 호출 후 저장한 배열을 자식 컴포넌트인 <CardList /> 에 넘겨주세요. (props 활용)
  • 넘겨준 후 CardList.js 에서 props 를 콘솔에 찍어 확인해주세요.
  1. API 호출 후 저장한 배열 = setState()로 업데이트 된 monsters의 state를 자식 컴포넌트인 <CardList />에 넘겨준다.
// Monsters.js
return (
      <div className="Monsters">
        <h1>컴포넌트 재사용 연습!</h1> 
        <SearchBox handleChange={this.handleChange}/>
        <CardList monsters={this.state.monsters}/> // task2 - mission1
      </div>
    );
  1. 넘겨준 후, CardList.js에서 처리할 수 있도록 props로 받아 온 값이 들어오는지 console을 통해서 확인한다.
// CardList.js

class CardList extends Component {
  render() {
    console.log(this.props.monsters) // task2 - mission2
    return <div className="card-list">
    </div>;
  }
}

export default CardList;
  1. console.을 통해 데이터가 잘 들어온 것을 알았으니, 이제 활용하면 되는구나...! 하고 알 수 있다. l love console..♥️

Task 3. Array.map( ) 사용

  • 🚨 Array.map() 함수 사용법을 꼭 익히고 시작해주세요!
  • 넘겨받은 배열을 기준으로 Array.map() 함수를 활용하여 <Card /> 컴포넌트를 리턴해주세요.
  • Card.js 에게 넘겨줘야하는 props 는 각 몬스터 객체의 id, name, email 입니다.
  1. Array.map()
    map() 함수는 여전히 어렵지만...! 😇

    this.props.monsters로 전달된 배열 데이터안의 요소만큼 돌면서 내가 지정한 <Card />라는 컴포넌트를 리턴하는 것이다.

  2. Card.js 에게 넘겨줘야하는 props
    map() 함수를 통해 전달된 데이터를 <Card />라는 컴포넌트로 전달해주기 위해서는 해당 데이터의 key값을 <Card />의 프로퍼티로 전달해주면 된다.

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

export default CardList;

Task 4. props 활용

  • Card.js 컴포넌트 모양 및 구조
    <div className="card-container">
    	<img src=이미지주소 alt="" />
    	<h2>Name</h2>
    	<p>Email</p>
    </div>
  • 이미지 주소 (src)
    https://robohash.org/숫자?set=set2&size=180x180
    카드마다 다른 이미지를 보여주기 위해 위 주소의 숫자 부분을 props 로 내려받은 id 로 대체해주세요.
  1. CardList.js에서 전달한 데이터를 props로 Card.js로 받아오기

    이미지, 이름, 이메일을 props로 받아와 주면 된다.

//Card.js
class Card extends Component {
  render() {
    return (
      <div className="card-container">
        <img src= {`https://robohash.org/${this.props.id}set=set2&size=180x180`} alt="monsterImage" /> // task4 - mission1 & 2
        <h2>{this.props.name}</h2> // task4 - mission1
        <p>{this.props.email}</p> // task4 - mission1
      </div>
    );
  }
}
  1. 카드마다 다른 이미지를 보여주기 위해 위 주소의 숫자 부분을 props 로 내려받은 id 로 대체

    😇 이 부분이 헷갈렸다...하하 백틱을 이용해서 사용하는게 참 쉬우면서도 어렵다. 결론은 src에도 props가 전달되어야하니까 {}를 사용해서 jsx를 쓴다는 것을 명시해 주고, 그 안에 또 변화하는 props값을 전달해줘야하니까 ${}를 사용해야한다. ${}안에는 id 값을 넣어주면된다 !!!
    이때, src는 하나의 문자열로 전달되어야하기 때문에 백틱으로 묶어주면 된다!!!

Task 5. Array.filter() 를 통한 검색기능 구현

  • SearchBox 컴포넌트에 정의한 handleChange 메소드를 넘겨준다.
  • 호출 시 인자로 들어오는 이벤트객체(e)를 활용해 userInput 으로 setState.
  • 여기서 비교 대상은 monster 객체의 name 값입니다.
  • 소문자로 바꾼 monster.name 값과 userInput값을 비교.
  • filter 메소드가 반환하는 값을 변수에 저장 후 return 문 안에 CardList에 props로 전달

필터 기능은 로직을 생각했지만 코드로 구현하기까지 힘들어서 구글링의 도움을 받았다.

✏️ 내가 생각한 로직

  • this.state.monsters에서 name이라는 key 값에 접근한다.
  • monster.name 값을 소문자로 바꾼다 : toLowerCase()
  • searchBox 컴포넌트에 입력된 input 값의 evnet.target.value와 2번의 결과값으로 나온 값이 일치하면 해당 카드만 보여준다.

뭔가 실행되기까지 많이 허술한 로직...

🔑 구현 방법

  1. 먼저, userInput값을 searchBox 컴포넌트로 전달해주어야했다. 이때 프로퍼티로 handleChange가 적혀있었다.

React state를 업데이트하기 위해 모든 키 입력에서 handleChange가 동작하기 때문에 사용자가 입력할 때 보여지는 값이 업데이트

  1. 그렇다면 handleChange를 통해 사용자가 입력할 때 보여지는 값이 업데이트되니까 이 값을 부모 컴포넌트에서 새로운 함수에 담아 자식 컴포넌트로 전달해주자.

🔥 이 부분이 내가 생각할 수 없는 부분이었다. 자식 컴포넌트에서 변화한 값을 받아 부모에서 함수를 만들어서 실행하다니..! 이건 다른 기능들에도 많이 쓰일 것 같다는 예감 100...

  1. 새로 정의한 handleSearchBox : ''이었던 userInput을 event.target.value로 입력된 값으로 바꿔주는 역할을 한다.
//Monster.js
 handleSearchBox = (event) => {
    this.setState({
      userInput: event.target.value
    })
  }
  1. 이렇게 정의된 handleSearchBox 는 props를 통해 searchBox.js로 전달된다.
//Monster.js : props 전달을 위해 입력해주기 !
  <SearchBox handleChange={this.handleSearchBox} />
//searchBox.js : props로 함수 받아오기

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

export default SearchBox;
  1. 함수가 잘 전달 되었나 console.log로 확인해보기 !

  1. 데이터 전달도 잘 되었으니 이제 monster 객체의 name 값(소문자로 바꾼 monster.name 값)과 userInput값을 비교하여 필터조건을 걸어주면 된다..! 말만 쉽다..ㅎㅎ

    🔑 먼저, 새롭게 배운 것이 있다. render() 함수 안에 변수를 정의 해줄 수 있다는 것이다.

    🔑 그래서 나는 filter 함수를 InputFiltering라는 변수에 저장하여 비교하기로 했다.

 const InputFiltering = this.state.monsters.filter((monsterName) => {
      return();
    })

이렇게 filter 함수를 정의해주고 내가 필터링해서 얻고싶은 값을 return()안에 넣어주면 된다. 내가 얻고 싶은 값1)소문자2)searchBox에 입력한 값3)포함4)몬스터의 이름이다.

//Monster.js 
return(
        monsterName.name.toLowerCase().includes(this.state.userInput)
      );

즉, 소문자로 입력한 userInput에 실시간으로 입력되는 값들이 포함된 몬스터이름을 찾아서 보여줘! 라는 이야기다.

🔥하.. 자바스크립트 문법 더 공부해야겠다는 의지가 활활

  1. 정의한 변수인 InputFiltering를 eturn 문 안에 CardList에 props로 전달해야한다.
//Monster.js 
<CardList monsters={this.state.monsters} InputFiltering={InputFiltering}/>
  1. 마지막으로 전달한 props 받아오기!!

처음엔 this.props.monster로 받아왔다면, 이젠 필터가 걸린 this.props.monster를 받아와야하기 때문에 이렇게 map() 함수를 돌리면 끝 !!!!

{this.props.InputFiltering.map((monsterList)=>{}

결론 : 지난 2주를 마무리 지은 과제

과제를 하기 전, 확실하게 props 개념에 대해서 알고 있는가에 대한 의문이 들었다. 기존에 작성한 html 코드를 react의 컴포넌트요소로, 또 여기에 state와 props를 적용하면서 나에게 새로 Input되어지는 지식들이 버겁고 정리가 안되있었다면, react 세션을 통해 배운 지식을 적용하고 내가 모르는 부분 ( map, filter 함수) 부분을 공부할 수 있었다.

profile
🍼 newbie frontend developer

0개의 댓글