좀더 깔끔하게 메소드를 리팩토링 하는 법

YEONGHUN KO·2022년 2월 9일
0

REACT JS - PRACTICE

목록 보기
1/15
post-thumbnail
post-custom-banner

Dadjokes 앱을 만들면서 콜트가 짠 코드를 보았다. 그리고 로직이나 메소드를 구성하는 측면에서 많은것을 배웠다 살펴보자.

  1. upvote/downvote 구현할때 나같은 경우는 jokeRow에다가 구현했다. 그것도 buttonType에 따라서 vote++/vote-- 를 해줬다. 요런식으로?
// JokeRow.js
handleVote(e) {
    const buttonType = e.target.innerText;
    if (buttonType === 'up') {
      this.setState(
        st => ({ score: ++st.score }),
        () => this.props.sort(this.state.score, this.props.id)
      );
    } else if (buttonType === 'down') {
      this.setState(
        st => ({ score: --st.score }),
        () => this.props.sort(this.state.score, this.props.id)
      );
    }
  }

근데 콜트는 역시 좀 다른것 같다. 부모 컴포넌트에다가 쌈빡하게 handleVote를 정리하고 그 메소드 자체를 JokeRow에 넘겨주었다

// DadJokes.js
// 여기서 말하는 delta는 +1 , -1을 의미한다.
handleVote(id,delta) {
   this.setState(st =>({
      jokes:[
         st.jokes.map(joke=> joke.id === id ?
         {...joke,vote:joke.vote+delta} :
         joke)
      ]
   }))
}

render() {
    const jokeRows = this.props.jokes.map(jokeObj => (
      <JokeRow
        id={jokeObj.id}
        upVote={()=>this.handleVote(id,1)}
        downVote={()=>this.handleVote(id,-1)}
        key={jokeObj.id}
        joke={jokeObj.joke}
      />
    ));
}

크... 진짜 쌈빡하다... 멋있다! 그냥 바로 완성된 메소드를 넘겨주는게 관건이다. 그리고 JokeRow에서 props를 통해 정의만 해주면 끝난다!

  1. vote에 따라서 색깔이 바뀌는 로직
    • 음... 난 최솟값 최대값을 정하고 배수에 따라서 dynamical하게 return하는 로직을 생각했는데 다른 분은 rgb를 바로 변경하는 방식을 사용하셨다.
   getRGB(rating) {
      if (rating > 0) return `${200 - rating * 20},200,0`;
      return `200,${200 - rating * -20},0`;
   }

  render() {
     const style={ border: `3px solid rgb(${this.getRGB(rating)})`}
  }

요런식으로 쌈빡하게 바뀜...

  1. 똑같은 joke는 제외하기
  • Dadjokes에서 불러온 모든 joke가 unique해야한다. 한개라도 같은게 있으면 안된다. 나는 역시나 find를 이용해서 일일이 다 찾은다음에 같은게 없으면 push하였다. 근데 우리 사랑스런 콜트는 set 자료구조를 이용하여 복사본을 제거하였다. 코드로 보자!
class JokeList {
  constructor(props) {
    super(props);
    this.state = {
      jokes: JSON.parse(localStorage.getItem('jokes') || '[]'),
    };
    this.seenJokes = new Set(this.state.jokes.map(j => j.text));
  }

  async getJokes() {
    try {
      let jokes = [];
      while (jokes.length < this.props.numJokesToGet) {
        let res = await axios.get('https://icanhazdadjoke.com/', {
          headers: { Accept: 'application/json' },
        });
        let newJoke = res.data.joke;
        // to prevent duplicate joke!
        if (!this.seenJokes.has(newJoke)) {
          jokes.push({ id: uuid(), text: newJoke, votes: 0 });
        } else {
          console.log('FOUND A DUPLICATE!');
          console.log(newJoke);
        }
      }
      this.setState(
        st => ({
          loading: false,
          jokes: [...st.jokes, ...jokes],
        }),
        () =>
          window.localStorage.setItem('jokes', JSON.stringify(this.state.jokes))
      );
    } catch (e) {
      alert(e);
      this.setState({ loading: false });
    }
  }
}

그리고 try/catch 구문을 사용해서 api에 문제가 생겼을시 에러에 의해 break되지않고 로딩이 자동 종료되도록 코드를 짰다. 역시 사랑스런 콜트이다...ㅋㅋㅋ

profile
'과연 이게 최선일까?' 끊임없이 생각하기
post-custom-banner

0개의 댓글