[WIL] 4주차 회고

Mark·2022년 8월 28일
0
post-thumbnail
post-custom-banner

공부한 내용

1. 리액트 라이프사이클

컴포넌트의 라이프 사이클은 정말 중요한 개념이며 컴포넌트가 렌더링을 준비하는 순간부터 페이지에서 사라질 때까지가 라이프 사이클이다.

1) 라이프 사이클의 3단계

  • 생성 → 수정(업데이트) → 사라짐
  • 생성(mount) : 실제 돔에 얹혀진다.
  • 수정(업데이트)는 사용자의 행동으로 데이터가 바뀌거나 부모 컴포넌트가 렌더링할 때 업데이트 된다.
    • props(부모→자식에게 주는 데이터)가 바뀔 때
    • state(내가 가진 데이터가)가 바뀔 때
    • 부모 컴포넌트가 업데이트(리렌더링) 되었을 때
    • 강제로 업데이트 했을 경우
  • 사라짐(unmount) : 페이지를 이동하거나, 사용자의 행동으로 인해 컴포넌트가 화면에서 사라지는 단계이다.

2) 클래스형 방식

초기화 단계

  • 초기화 단계는 최조에 컴포넌트 객체가 생성 될 때 한번 수행되는 과정

초기화 단계에서 실행되는 함수

  • constructor()
    • 생성자 함수라고도 부르며 컴포넌트가 생성되면 가장 처음 호출된다.
    • react 컴포넌트의 생성자는 해당 컴포넌트가 마운트 되기전 호출된다.
    • 생성자를 구현하면 this.props가 생성자 내에서 정의되도록 super(props)를 호출해야 한다.
    • state값을 변경하고자 한다면 constructor외부에서 this.setState를 통해 수정해야 한다.
    constructor(props) {
    	super(props);
    	this.state = { count: 0 };
    }
  • render()
    • class 컴포넌트에서 반드시 구현되어야 하는 유일한 메서드이다.
    • 이 메서드를 호출하면 this.props와 this.state값을 활용해 값을 반환해야 한다.
    • 컴포넌트의 모양을 정의한다.
    • render() 함수는 컴포넌트의 state를 변경하지 않고 호출될 때마다 동일한 결과를 반환하며 브라우저와 직접적인 상호작용을 하지 않는다.
    • render() 안에 들어갈 내용은 컴포넌트의 모양에만 관여하는 것이 가장 좋다.
    • state나 props를 건드려서 데이터를 수정하면 안된다.
  • componentDidMount()
    • 첫 번째 렌더링을 마친 후에 딱 한 번 실행된다.
    • 컴포넌트가 리렌더링할 때는 실행되지 않는다.
    • 보통 ajax 요청, 이벤트 등록, 함수 호출등 작업을 처리한다.
    • 이미 가상돔이 실제돔으로 올라간 후라서 DOM 관련 처리를 해도 된다.

업데이트 단계

  • 업데이트 단걔는 컴포넌트가 마운트 된 이후 컴포넌트의 속성값, 상태값이 변경되면 업데이트 단계가 실행된다.

업데이트 단계에서 실행되는 함수

  • componentDidUpdate()
    • render가 일어난 직후에 호출되며 최초 렌더링에서는 호출되지 않는다.
    • 이 함수에서는 중요한 파라미터 2개가 있다. (prevProps, prevState) 각각 업데이트 되기 전 props, state이며 이전 데이터와 비교할 일이 있다면 사용함녀 된다.
    • DidUpdate()가 실행될 때도 가상돔이 실제돔으로 올라간 후라서 DOM관련 처리를 해도 된다.

소멸 단계

  • 소멸 단계에서는 컴포넌트가 소멸 할 때의 과정이다.

소멸 단계에서 함수

  • componentWillUnmount()
    - 컴포넌트가 마운트 해제되어 제거되기 직전에 호출된다.
    - 타이머 제거, 네트워크 요청 취소, componentDidMount()에서 생성된 작업등을 정리할 때 사용된다.
    - 실행 직후 컴포넌트는 렌더링 되지 않으므로 setState() 호출을 하면 안된다.

3) 함수형

useEffect : 리액트 훅에서 라이프사이클 구현에 사용되는 함수이다.

  • useEffect 사용 방법
    • 2번째 파라미터를 주지 않으면 컴포넌트가 리렌더링될 때마다 실행된다.(메모리 과다 사용)

      useEffect(() => {
       // 코드 적는 곳
      
      })
      
  • componentDidMount()를 대신 사용시, 렌더링 완료된 후에 호출되는 메소드
    • 마운트 이후 1회만 실행

      useEffect(() => {
         
      }, []) // 빈 배열을 줌으로써 마운트 이후 딱 1회만 실행
  • componentDidUpdate() & getDerivedStateFromProps() : 컴포넌트 업데이트 작업 완료 후 실행되는 메서드
    • 2번째 파라미터 배열에 명시한 변수가 변경될 때만 실행

      useEffect(() => {
        // 코드 적는 곳
      }, [props명, state명,...])
  • componentWillUnmount() : 컴포넌트가 DOM에서 제거될 때 호출되는 메서드
    - effect(함수 혹은 변수 등)이 필요없어질 때 return 함수를 실행해 메모리를 반환한다.
    useEffect(() => {
    	// 코드 적는 곳
        
        return () => {
        	//  unmount나 unsubscribe 코드
        }
    }, [props명, state명, ...])

2. 리액트 Hooks

1) Hook이란?

  • 함수 컴포넌트에서 React state와 생명주기 기능을 연동할 수 있게 해주는 함수이다.
  • 훅은 class 안에서는 동작하지 않는다. class 없이 React를 사용할 수 있게 해준다.

2) Hook 사용 시 규칙

  • 함수형 컴포넌트에서만 쓸 수 있다.
    • React Function 내에서만 쓸 수 있다.
    • 리액트 함수는 리액트의 규칙을 따르는 함수
    • 함수형 컴포넌트와 커스텀 훅이 대표적이다.
  • 컴포넌트의 최상위에서만 호출 할 수 있다.
    - 반복문, 중첩문 내에서는 호출할 수 없다.
    - 반복문, 중첩문 등에서 훅을 호출하게 될 경우, 컴포넌트가 렌더링할 때 훅의 실행 순서를 늘 동일하게 보장해줄 수 없다.

3) 자주 사용하는 Hook

  • useState()
    • useState()는 상태관리를 위한 훅이다.

    • useState()는 값을 넣어두고 참조하기 위한 변수(state 변수), 값을 바꿔주기 위한 함수를 반환한다.

      const [value, setValue] = useState("hi!");
    👉 구조 분해 할당
    구조 분해 할당은 자바스크립트 표현식 중 하나로, 
	배열이나 객체의 속성을 해체해서 각각의 값을 개별 변수에 할당해준다. 
	배열이나 객체의 속성을 해체해서 각각의 값을 개별 변수에 할당해준다. 
    위의 예시 코드에서는, const [value, setValue] = useState(”hi!”); 에서 
	useState는 [a, b]를 리턴해주고 있고, a와 b를 한 번에 가져오기 위해 [value, setValue]로 받아오는 것이다.
  • useEffect()
    • useEffect()는 컴포넌트의 사이드 이펙트 관리를 위한 훅이다.
    • 리액트 컴포넌트가 렌더링될 때마다 특정 작업을 수행할 수 있도록 설정하는 훅이다.
    • 즉, Mount, Update, Unmount 될 때 특정 작업을 처리할 코드를 실행시키고 싶을 경우 useEffect를 사용하면 된다.
    • useEffect 훅은 인자로 callback함수를 받는다.
    • 의존성 배열을 통해 함수의 실행 조건을 제어할 수 있다.
    • useEffect에서 함수를 1번만 실행시키고 싶을 경우 의존성 배열을 빈 배열로 둔다.
      useEffect(() => {
      	// 작업...
      }, [value]);
  • useCallBack()
    • useCallBack()는 함수를 메모이제이션 하기 위한 훅이다.
    • 함수를 최적화하기 위한 방법 중 하나이다.
    • React.memo와 함께 사용해서 불필요한 렌더링 방지를 위해 사용한다.
    • 하지만 useCallBack()을 사용한다고 해서 무조건 렌더링 횟수가 줄어드는 것은 아니다. 무분별한 메모지에이션은 좋지 않다.
    • 주로 자식 컴포넌트에게 props로 넘기는 콜백함수를 감싸는 데에 쓰인다.
    • useEffect와 마찬가지로 인자는 2개이다.
      • 첫번째 인자는 실행할 콜백 함수이다.
      • 두번째 인자는 디펜던시 어레이라고 불리는 의존성 배열이다.
      • 배열에 넣은 어떤 값이 변했을 때 콜백 함수를 새로 생성하고 다시 메모이제이션한다.
    👉 메모지에이션이란?
    - 메모리 어딘가에 저장해두고 두고두고 사용한다는 의미
    - 함수형 컴포넌트가 리렌더링되면 컴포넌트 안에 선언해둔 함수나 인라인으로 작성한 함수를 다시 한 번 생성하게 된다. 
    - 어떤 컴포넌트가 총 10번 렌더링된다면 그 안에 작성해둔 함수들도 10번 만들어지는 것이고, 메모리 관리에 효율적이지 않다.
    - useCallBack()은 함수를 메모이제이션해서 여러번 만들지 않도록 해준다. 
    - 주로 자식 컴포넌트에게 전달해주는 콜백 함수를 메모리제이션할 때 쓴다.
    
	const myNewFunction = useCallback(() => {
     console.log("hey!", need_update);
    }, [need_update]);입력하세요
  • useRef()
    • useRef()는 ref객체를 다루기 위한 훅이다.

    • 어떤 값을 넣어주면 그 값으로 초기화된 변경 가능한 ref객체를 반환해준다.

    • 이 값은 원본이 아닌 똑같이 생긴 다른 값이기 때문에 변경도 가능하다.

    • 변경해도 리렌더링이 일어나지 않는다.

      const Input = () => {
      
        const input_ref = React.useRef(null);
      
        const clicker = (input_ref) => {
          console.log(input_ref);
        }
        
        return (
          <>
            <input ref={input_ref}/>
            <button onClick={clicker}>button</button>
          </>
        );
      }
    • .current

      • useRef는 .current 안에 값을 담아준다.
      • 이 값을 변경해도 리렌더링은 일어나지 않는다.
    • useRef()는 주로 화면에 이미 노출된 것들을 관리할 때 사용한다.

      • 인풋을 다루거나
      • 버튼 클릭 후, 특정 상황에서 어떤 인터렉션을 보여주고 싶을 경우
    • DOM만을 위한 것은 아니다.

      • 엘리먼트 외에도 특정 값을 다루기 위해 사용할 수 있다.

3. 리액트 스터디

리액트 Redux 상태관리와, 페이지 이동을 시키는 React-router-dom, 기존 css로 적용했던 styles들을 styled-components로 적용하기 위한 스터디를 했다.

  • 리액트 라이프 사이클
  • 리액트 Hooks - useRef, useState, useEffect, useCallback
  • styled-components
  • react-router-dom
  • Redux

4. 자바스크립트 스터디

투두리스트를 구현하는데 있어서 필요하거나 그 외의 추가적으로 알고 있어야 하는 자바스크립트 개념에 대한 스터디를 진행하였다.

  • [JavaScript] 동시성
  • [JavaScript] Promise
  • [JavaScript] async, await
  • [JavaScript] switch문

5. [개인프로젝트] ToDoList

1) 구현한 기능

  • [ToDo] Redux - 할 일 등록하기
  • [ToDo] Redux - ToDo 조회하기
  • [ToDo] Redux - 할 일 삭제하기
  • [ToDo] Redux - 할 일 상태(완료, 취소) 체크

2) 해당 기능을 구현하는데 있어서 꼭 알고있어야 하는 개념

  • 전개연산자
  • map 메서드
  • filter 메서드
  • 구조 분해 할당
  • 리액트 훅(useState)
  • 리액트 라이프사이클
  • Redux 개념 및 상태관리

6. 배운점, 어려웠던 점

1) styled-component를 사용할 때 css를 분리하고 외부에서 사용할 수 있도록 export 시키는 과정에서 {…rest}를 사용하는지 모르겠었음

  • 통채로 속성들을 넘기게 될 경우 …rest를 사용해서 넘겨주면 된다. 만약 그 속성들을 styled-component로 넘겼는데 속성들 중에서 추가적으로 변경해야 할 값이 있다면 …rest가 아닌 title, content 이런 식으로 속성들을 풀어서 넘겨주면 된다.
  • 예를 들어 input 태그에서 placehorder, name, value라는 속성들이 따로 수정이 필요하지 않고 styled-component 파일(자식요소)로 전달하고자 한다면 자식요소에서 …rest로 받으면 된다.

2) Redux를 왜 사용하는가? 명확히 이해가 안되었다.

❓ 초반에 useState를 사용하는 것과 Redux를 사용하는 것에 대한 큰 차이를 느끼지 못해서 발생한 의문이었다.

  • 내가 이해한 바로는 리덕스를 사용하지 않을 때 가장 큰 문제점인 인자로 값을 전달 받아야 할 경우 부모 → 자식 컴포넌트로 이동시 중간에 전달받지 않아도 되는 컴포넌트까지 자식 컴포넌트로 전달하기 위해서 불필요한 전달을 하게될 수 있다. 하지만 리덕스를 사용하면 내가 사용하고 싶은 데이터를 저장소에서 꺼내서 쓸 수 있다는 점이 큰 차이점인 것 같다. 즉 부모 컴포넌트 → 자식 컴포넌트로 인자를 이동시키면서 전달하지 않아도 해당 컴포넌트가 필요로 하는 데이터를 뽑아서 가져올 수 있다는 것이 장점인 것 같다.

3) 스토어와 모듈 연결시 주의할 점

  • 스토어와 모듈 연결시, 반드시 export한 모듈 함수명으로 import시켜서 연결해야 하며, useSelector로 값에 접근할 때도 export 시킨 리듀서 함수 이름으로 접근해줘야 에러가 발생하지 않고 잘 연결된다.

4) delete todo시, 데이터가 완전히 삭제되는 것인지, 남아 있는 것인지?

❓ delete todo를 할 때 이전 데이터가 메모리에서 아예 삭제되는 것인지, 아니면 새로운 배열로 업데이트 시켜서 보여주는 것이고 이전 데이터는 메모리에 남아있는 상태인지 명확하게 이해가 안되었다.

  • filter 메서드로 id값이 다른 값만 찾아서 새로운 배열 객체로 반환했으면 이전 데이터는 완전히 삭제되는 것이 아니라, 메모리에 남아 있는 상태일 것이다.

5) todo.length를 사용하면 안되는 이유?


7. 멘토님과 Q&A

1) 라이브러리 의존성을 낮추는 것이 좋다.

  • 개인프로젝트, 프로젝트를 진행할 때 라이브러리를 사용하면 편하다는 장점이 있지만 면접을 보거나 포트폴리오를 작성할 때 라이브러리를 사용해서 구현하는 것보다 본인이 라이브러리를 사용하지 않고 어떻게 해결했는지가 중요하고 연습을 해야한다.

2) styled-component사용시 줄임말은 피하기

  • styled-component뿐만 아니라 파일명이나, 변수명 설정시, 너무 줄임말을 사용하면 협업시, 다른 사람이 코드를 이해하기 어려울 수 있다. 나만 알도록 작명을 하지 않고 모두가 이해할 수 있고, 직관적으로 해야한다.
  • 카멜 케이스 지켜줘야한다.
  • 되도록 풀 네임으로 사용해주는 것이 좋다.

3) 타입스크립트를 왜 써야 하는지?

  • 타입스크립트 공부는 필수적으로 하는 것이 좋다.
  • 가장 큰 장점은 왜 에러가 뜨는지 정확하게 알 수 있다.
  • 협업 시, 오류가 발생한 원인을 모를 때 오류를 상세히 알려주기 때문에 타입스크립트를 사용하기 좋다.

4주차 리액트 입문을 마치며

이번 주차는 저번 주차에서 진행했던 투두리스트를 가지고 redux를 적용해서 상태관리를 하는 프로젝트였다.

처음엔 redux에 개념에 대해서 이해를 해도 리덕스가 가진 가장 큰 장점을 제대로 활용할 줄 몰라서 굳이 useState를 안쓰고 redux를 왜 사용해야 하는지 차이점이 쉽게 분간이 안되었는데, 프로젝트를 하면서 redux의 장점과 상태관리의 장점을 제대로 느낄 수 있는 시간이었다.

대신 언제나 리덕스를 사용하는 것은 좋은 선택이 아닐 수 있고, 프로젝트 규모에 따라 본인이 판단하에 리덕스를 사용하는 것이 좋을 수 있다. (리덕스 자체가 무겁기 때문 등등)
또한 팀원분들과 서로 궁금한 점, 어려운 점 모르겠는 점들을 공유하면서 내가 간과하고 있었던 부분들도 함께 찾아보게 되고, 그런 과정속에서 정말 많은 도움과 학습이 되었던 것 같다.

아쉬웠던 점

이번 주차에는 저번 주차와 달리 정말 사소한 것이라도 내가 이해하고 있지 않거나, 모르면 멘토님들에게 약간 더 적극적으로 질문을 하면서 궁금증, 문제를 해결하고자 노력했다.

확실히 혼자서 찾아보고 알아보는 것보다 더 명쾌하게 궁금증이 해결이 되었다.


참고 자료

profile
개인 공부 정리
post-custom-banner

0개의 댓글