TIL 51 | 첫 React 프로젝트, 주요 리뷰 정리

meow·2020년 9월 8일
0

React

목록 보기
11/33

자바스크립트로 만들었던 인스타그램 클론을 React, Sass로 바꾸고 동일한 기능을 구현했다. 그 과정에서 마주한 장벽, 해결법, 그리고 뼈가 되고 살이 되는 멘토의 리뷰를 기록하고 정리한다.

ADD

1. Child Component에는 Unique Key가 필요해요.

댓글, 아티클 등 반복적인 컨텐츠는 자식 컴포넌트로 관리하면 편리하다. 주로 데이터를 map을 돌리는 방식으로 동적인 컨텐츠를 생성하는데, 이때 반드시 각각의 요소에 유니크한 키를 부여해주어야 한다. index를 키로 사용하는 것은 지양하고, author의 id, new Date.getTime() 등을 활용하면 좋다.

// Unique Key 적용 예시
  addComment = (e) => {
    e.preventDefault();
    const { comment, list } = this.state;
    if (comment) {
      this.setState({
        list: [
          ...list,
          {
            id: "thisisyourhyung",
            content: comment,
            key: `thisisyourhyung-${new Date().getTime()}`,
          },
        ],
        comment: "",
      });
    }
  };
<ul className="comments">
  {this.state.list.map((comment) => (
    <Comment
      key={comment.key}
      commentKey={comment.key}
      commentId={comment.id}
      commentContent={comment.content}
      onDelete={this.deleteComment}
    />
  ))}
</ul>

추가로, key는 props.key로 사용이 불가능하다. key는 컴포넌트의 구성요소로 전달되지 않기 때문이다. key 값을 읽어와야 한다면, 다른 props에 key를 담아 읽어와야 한다.

참고자료 : [React.JS] List와 Key

2. <form>onSubmit 이벤트를 실행시켜보세요.

onKeyPress={(e) => e.key === "Enter" && this.addComment()}

대신에 input을 form 태그로 감싸고 form 태그에 onSubmit 이벤트를 실행시켜주는 방법을 사용할 수 있다. form 태그 사용시 e.preventDefault() 함수를 실행시켜 state 값을 유지될 수 있게 해주어야 한다!

FIX

3. 합칠 수 있는 함수는 축약해보세요.

3-1 코드

// AS IS
  handleSubmit = (e) => {
    if (!this.canBeSubmitted()) {
      e.preventDefault();
      return;
    }
  };
  canBeSubmitted() {
    const { id, password } = this.state;
    return id.includes("@") > 0 && password.length >= 5;
  }
// TO BE
  handleSubmit = (e) => {
    const { id, password } = this.state;
    const isValid = id.includes("@") > 0 && password.length >= 5;
    
    if (!isValid) {
      e.preventDefault();
      return;
    }
  };

3-2 코드

이렇게 둘을 나눠서 함수를 작성하기 보다는 하나로 합치는 방법도 있습니다. 저희가 해야하는건 입력된 값에 따라서 matchArr만 제대로 관리해주면 return문 아래에서 알아서 render 되기 때문에 좀 더 심플하게 생각하셔도 될 것 같습니다! - by 갓준식

// AS IS
  handleChange = (e) => {
    this.setState({ searchValue: e.target.value });
  };

  checkMatch = () => {
    const { searchValue, userArr, matchArr } = this.state;
    if (searchValue) {
      this.setState({
        matchArr: userArr.filter((x) => x.id.indexOf(searchValue) !== -1),
      });
    } else {
      this.setState({
        matchArr: [],
      });
    }
    return matchArr;
  };
// TO BE
  checkMatch = (e) => {
    const searchValue = e.target.value;
    const { userArr } = this.state;
    this.setState({
      matchArr:
        searchValue !== ""
          ? userArr.filter((el) => el.id.includes(searchValue))
          : [],
    });
  };

4. className이 아닌 src를 토글하는 방식은 어때요?

// AS IS
<img
  alt="하트"
  className={this.state.heartClick ? "heart-on" : "heart-off"}
  src="https://s3.ap-northeast-2.amazonaws.com/cdn.wecode.co.kr/bearu/heart.png"
/>
<img
  alt="좋아요된하트"
  className={this.state.heartClick ? "heart-off" : "heart-on"}
  src="img/liked.png"
/>
// TO BE
<img
  onClick={this.toggleLike}
  alt="하트"
  className="comment-like"
  src={
    heartClick
      ? "https://s3.ap-northeast-2.amazonaws.com/cdn.wecode.co.kr/bearu/heart.png"
      : "img/liked.png"
  }
/>

5. 고정 데이터는 state로 관리할 필요가 없어요.

state는 바뀌는 UI에 대한 데이터를 효율적으로 관리하기 위한 용도다.

6. 반복되어 사용되는 함수가 아니라면 return문 안에서 바로 함수를 실행시켜도 좋아요.

// Example
onBlur={() => this.setState({ focusIn: false })}
onFocus={() => this.setState({ focusIn: true })}

7. falsy value와 truthy value를 따로 관리할 필요는 없어요.

const isValid = comment !== "";
this.setState({ isBtnActive: isValid });

comment가 빈 문자열이라면 falsy value이기 때문에 굳이 isBtnActive 상태를 따로 관리할 필요가 없다.

8. true의 결과만 있는 삼항연산자는 이렇게 써보세요.

// AS IS
e.key === "Enter" ? this.commentInput() : null
// TO BE
e.key === "Enter" && this.commentInput()

REFACTOR

9. 비구조화 할당(destructuring)을 적용해주세요.

// Example
  render() {
    const { img, id, nickname } = this.props;
    
    return (
      <li className="Searchresult">
        <img
          className="img-profile"
          src={img}
          alt={id + "님의 프로필 사진"}
        />
        <div className="profile-text">
          <span className="userID point-span">{id}</span>
          <span className="sub-span">{nickname}</span>
        </div>
      </li>
    );
  }

10. Template literal 사용을 생활화합시다!

// AS IS
alt={this.props.id + "님의 프로필 사진"}
// TO BE
alt={`${this.props.id}님의 프로필 사진`}
profile
🌙`、、`ヽ`ヽ`、、ヽヽ、`、ヽ`ヽ`ヽヽ` ヽ`、`ヽ`、ヽ``、ヽ`ヽ`、ヽヽ`ヽ、ヽ `ヽ、ヽヽ`ヽ`、``ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ`ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ、ヽ、ヽ``、ヽ`、ヽヽ 🚶‍♀ ヽ``ヽ``、ヽ`、

0개의 댓글