TIL-27

정진우·2021년 7월 9일
0

TIL

목록 보기
27/54
post-thumbnail
post-custom-banner

20210709
React Hook(useState)
함수형 컴포넌트 / 클래스형 컴포넌트

Hook이란?

  • 함수 컴포넌트에서 React state와 생명주기 기능(lifecycle features)을 “연동(hook into)“할 수 있게 해주는 함수
  • class를 작성하지 않고도 state와 같은 React 기능 사용 가능하게 함(class 안에서는 동작하지 않음)
  • 계층의 변화 없이 상태 관련 로직을 재사용할 수 있도록 도와줌
  • 서로 비슷한 기능을 하는 작은 함수의 묶음으로 컴포넌트를 나눌 수 있게 도와줌

React 내장 hook - useState

  • 상태 유지 값과 그 값을 갱신하는 함수를 반환
  • 최초로 렌더링을 하는 동안, 반환된 state는 첫 번째 전달된 인자(initialState)의 값과 같다.
const [state, setState] = useState(initialState);
  • 배열 구조 분해 ... 2개의 값(state, setState)을 만든다.
  • 변수는 아무 이름으로 지어도 된다.
  • 클래스형 컴포넌트의 this.state가 제공하는 기능과 동일하다.
  • 일반 변수는 함수가 끝날 때 사라지지만, state 변수는 React에 의해 사라지지 않는다.


setState

setState(newState);
  • state를 갱신할 때 사용
  • 새 state 값을 받아 컴포넌트 리렌더링을 큐에 등록
  • 다음 리렌더링 시에 useState를 통해 반환받은 첫 번째 값은 항상 갱신된 최신 state가 됨




커뮤니티 사이트를 만들 때 사용한 LikeBadge 컴포넌트를 예시로 함수형 컴포넌트, 클래스형 컴포넌트, 그리고 useState에 대해서 설명해보겠습니다.

먼저, 클래스형으로 만든 LikeBadge 컴포넌트입니다.

class LikeBadge extends React.Component {

	constructor(props){
    super(props);
    this.state = {
      likes: 0,
      updated: false,
      color: 'gray',
    };
  }
  updateLikes = () => {
    if(!this.state.updated) {
      this.setState((prevState, props) => {
        return {
          likes: prevState.likes + 1,
          updated: true,
          color: 'red',
        };
      });
    } else {
      this.setState((prevState, props) => {
        return {
          likes: prevState.likes - 1,
          updated: false,
          color: 'gray',
        };
      });
    }
  }
render() {
    const _session_key = `firebase:authUser:${apiKey}:[DEFAULT]`;
    const is_session = sessionStorage.getItem(_session_key)? true: false;
    
    if(is_session) {
        return (
            <React.Fragment>
                <div><FavoriteIcon style={{verticalAlign: 'middle', color:this.state.color}} onClick={this.updateLikes}>좋아요</FavoriteIcon>{this.state.likes}개</div>
            </React.Fragment>
        )
    }
    return (
      <div><FavoriteIcon style={{verticalAlign: 'middle', color:'gray'}}></FavoriteIcon>{this.state.likes}개</div>
    );
  }
}
  • 위에서부터 천천히 읽어보겠습니다.
  • 클래스형 컴포넌트를 정의하려면 React.Component를 상속받아야 합니다.
  • this 키워드를 사용하려면 생성자(constructor) 함수 안에 super(props)를 선언해야 합니다.
  • 그리고, this.state에 객체를 할당하여 지역 state를 초기화합니다.
  • setState를 이용해 state 값을 변경해줍니다.(updateLikes함수는 버튼은 누르면 color가 빨간색/회색으로 바뀌고 likes는 +1/-1 되고 updated 도 true/false로 바뀌는 기능을 가지고 있습니다.)
  • render()는 React.Component의 하위 class에서 반드시 정의해야 하는 메서드입니다.

다음으로, 함수형으로 만든 LikeBadge 컴포넌트입니다.

function LikeBadge (props) {
  let [likes, setLike] = useState(0);
  let [updated, setUpdated] = useState(false);
  let [color, setColor] = useState('gray');

  const updateLikes = () => {
    if(!updated) {
      setLike(likes + 1);
      setUpdated(updated = true);
      setColor(color = 'red');
    } else {
      setLike(likes - 1);
      setUpdated(updated = false);
      setColor(color = 'gray');
    }
  }
const is_login = useSelector((state) => state.user.is_login);
  const _session_key = `firebase:authUser:${apiKey}:[DEFAULT]`;
  const is_session = sessionStorage.getItem(_session_key)? true: false;
    if(is_login && is_session) {
        return (
            <React.Fragment>
                <div><FavoriteIcon style={{verticalAlign: 'middle', color:color}} onClick={updateLikes}>좋아요</FavoriteIcon>{likes}개</div>
            </React.Fragment>
        )
    }
    return (
      <div><FavoriteIcon style={{verticalAlign: 'middle', color:'gray'}}></FavoriteIcon>{likes}개</div>
    );
}
  • 위에서 설명한 useState를 사용해서 likes와 그 값을 갱신하는 함수인 setLikes를 선언해주고 초기값도 0으로 설정했습니다.
  • 그 아래 변수, 함수들도 같은 방식입니다.
  • updateLikes라는 함수를 선언해줬고 값을 갱신하는 함수들(setLike,setUpdated,setColor)을
    사용해서 값을 변경해주었습니다.



위의 내용들을 정리해보자면, 클래스형 컴포넌트는 state 관련 기능 사용이 가능하지만, 함수형 컴포넌트는 state 관련 기능을 사용할 때 Hook(useState)을 사용해야 합니다.
profile
프론트엔드 개발자를 꿈꾸는
post-custom-banner

1개의 댓글

comment-user-thumbnail
2021년 8월 2일

TIL에도 높임말 하시나요 ? 예의바르시네요 ...

답글 달기