TIL

[Day 34] 2022-0809

프라이D 2022. 8. 9. 22:05

🐈오늘 공부한 것

✔️리액트 : 데이터 흐름과 state 끌어올리기

리액트는 위에서 아래로 흐르는 단방향 데어트 흐름을 가지고 있다. 상위 컴포넌트에서 하위 컴포넌트로 props를 통헤 데이터를 전달할 수는 있지만, 하위 컴포넌트에서 상위 컴포넌트로 데이터를 전달할 수는 없다. 만약 하나의 state에 의해서 여러 컴포넌트가 영향을 받는다면, 영향을 받는 해당 컴포넌트의 공통 컴포넌트에 state를 위치시켜야 한다. 그리고 props로 state를 변경할 수 있는 setter 함수를 전달하여, 하위 컴포넌트에서 실행시킨다. 이를 통해 하위 컴포넌트에서 상위 컴포넌트에 위치한 state의 상태를 변경할 수 있고, 이를 state 상태 끌어올리기라고 표현한다. 이 방법을 사용하면 리액트의 단방향 데이터 흐름 원칙에 위배되지 않을 수 있다! 

✔️리액트로 사고하기 : 리액트로 앱 만드는 과정

리액트 공식문서에 있는 리액트 앱을 만드는 단계를 요약한 내용이다. 리액트로 개발을 시작할 때 어떤 단계부터 접근해야할지 좀 막막했는데 오늘 잘 정리가 된 것 같다. 

1. UI 컴포넌트를 계층 구조로 나눈다.
: 컴포넌트가 될 부분들을 단일 책임 원칙에 따라서 구별하고 계층화한다. (트리 구조로 표현할 수 있다.)
2. React로 정적인 버전을 만든다. 
: 데이터 모델을 가지고 변화 없이 렌더링만 되는 정적인 버전을 제작한다. state는 배제하고 우선 props를 가지고 제작한다.
+ 컴포넌트는 하위 컴포넌트를 제작한 뒤 이를 조립해 상위 컴포넌트를 만드는 상향식으로 접근한다. 간단한 프로젝트에서는 하향식 방식이 편할지 몰라도, 규모가 커질수록 상향식으로 개발하고 테스트를 하는 것이 더 쉽다. 
3. state - 변해야 하는 부분을 찾아낸다. 
: 꼭 필요하면서 중복되지 않는 최소한의 state만 찾는다. 계산될 수 있거나, props로 전달될 수 있으면 state가 아니다. state가 많을수록 앱이 복잡해지고, 또 state가 리렌더링을 발생시키기 때문에 성능 측면에서도 state가 적을수록 좋다고 한다. 
4. state의 위치를 선정한다. 
: state를 기반으로 렌더링하는 모든 컴포넌트를 찾고, 공통의 컴포넌트에 state를 위치시킨다. 만약 마땅한 공통 컴포넌트가 없다면, 새로 하나 만든다(!)
5. 역방향 데이터 흐름 추가 (state끌어올리기)
: 하위 컴포넌트에 state setter 함수를 전달하고, 하위 컴포넌트에서 실행한다.

✔️Side Effect 부수 효과

Side Effect 란 함수 내부의 구현이 함수 외부에 영향을 끼치는 것을 의미한다. 리액트의 컴포넌트는 하나의 컴포넌트가 하나의 기능만을 수행하고 또 동일한 데이터에 대해 동일한 결과를 보장하는 순수함수이다. (그래서 props도 읽기 전용이다.) Side Effect에는 화면 렌더링 이후에 비동기적으로 실행되는 Ajax 호출 등이 포함된다. 이런 Side Effect를 컴포넌트 내부에서 실행시키기 위해서 useEffect Hook을 사용한다. 자료를 찾아보니 Side Effect를 useEffect 훅 내에서 실행시키는 이유가 성능과 라이프 사이클에 관련이 있다는 것 같은데, 자세한 내용은 참고자료를 보고 천천히 공부해야겠다. 

✔️리액트 : 라이프 사이클과 useEffect Hook

리액트 컴포넌트의 라이프 사이클은 마운트 - 업데이트 - 언마운트 로 구분할 수 있다. 마운트는 컴포넌트가 화면에 처음 나타나는 것이고, 업데이트는 변경으로 인해 리렌더링 되는 것, 언마운트는 화면에서 사라지는 것이다. useEffect 훅을 사용하면 특정 작업(side effect를 발생시키는 fetch 같은 것들) 을 라이프 사이클에 맞춰 특정 시점에 실행시킬 수 있다. 첫 번째 인자로는 실행시킬 콜백함수, 두 번째 인자로는 종속성 배열 (dependency array)를 받는데, 종속성 배열 내에 요소가 있다면 "해당 요소가 업데이트 될 때만" 함수를 실행시킬 수 있다. 빈 배열이라면 최초 마운트가 되었을 때만 실행된다. 또 콜백함수에 clean up 해줄 함수를 리턴하면 해당 컴포넌트가 언마운트 될 때 clean up 함수가 실행된다. 종속성 배열이 없으면 어떤 것이든 변화가 일어날 때마다 함수가 실행되기 때문에 비효율적이다. 따라서 종속성 배열을 꼭 함께 사용하자! 

✔️리액트 : 조건부 렌더링

const [isLoading, setIsLoading] = useState(true);
//..생략

useEffect(() => {
    setIsLoading(true);
    // AJAX 호출 함수
    getFlight(condition).then(res => {
      setFlightList(res);
      setIsLoading(false);
    });
  }, [condition]);

return (
  {isLoading ? <LoadingIndicator /> : <FlightList list={flightList} />}
};

로딩 여부를 state로 등록하여 Ajax 호출 전, 후로 상태를 변경하여 그 조건에 따라 렌더링 되는 컴포넌트를 다르게 할 수 있다!

🐈더 공부할 것

1. AJAX 호출을 사용하는 토이 프로젝트 만들기

2. 타입 스크립트 문법 정리

🐈오늘의 느낀 점

1. 오늘은 useEffect를 공부하면서 마운트, 언마운트 개념과 리액트의 렌더링 개념에 대해서 조금 더 알아볼 수 있었다. 기존 DOM 을 사용한 방식에서 DOM의 변화를 감지해 모든 렌더링 과정이 일어났다면, 리액트에서는 가상 DOM을 활용해 변화되는 부분만 업데이트 한다는 것? 바닐라 자바스크립트에서는 '특정 DOM 을 가져와 그 데이터를 변경하고 어떤 일이 일어났을때 어떻게...'라는 절차가 있었다면 리액트에서는 '이것 이것, 바꾼다. '로 간소화 된 느낌이었다. 내가 데이터를 바꾸면, 화면은 리액트가 바꿔준다. 

 

2. 오늘 과제가 생각보다 일찍 끝나서, 내일은 페어 분과 함께 다른 연습을 해보기로 했다. 근데 아직 뭘 할지 못정했는데... 일단 투두 리스트 처음부터 만들면서 복습하기? 거기에 AJAX 데이터 받아오는 연습까지 추가? 하루 안에 이 정도 분량은 할 수 있을 듯? 

 

3. 비가 와서 계속 밖에 나가지 못하니 힘들다 ㅜㅜ