리엑트의 데이터는 아래로 흐릅니다
- 리엑트의 각 컴포넌트는 데이터를 부모로부터 전달 받습니다(데이터 흐름이 하향식(top-down)임을 의미합니다.) 또 컴포넌트는 props를 통해 전달받은 데이터가 어디서 왔는지 전혀 알지 못합니다.
- 어떤 데이터를 같이 공유하고 있는 상황에, 하위 컴포넌트(NewTweetForm)에서의 클릭 이벤트가, 부모의 상태를 바꾸어야만 하는 상황이 있다면, 이를 어떻게 해결할 수 있을까요?
이를 해결할 수 있는 키워드는 바로 "State 끌어올리기(Lifting state up)" 입니다.
상태 끌어올리기
- 하위 컴포넌트에서의 어떤 이벤트로 인해 상위 컴포넌트의 상태가 바뀌는 것은 마치 "역방향 데이터 흐름"과 같이 조금 이상하게 들릴 수 있습니다. React가 제시하는 해결책은 다음과 같습니다.
- 상위 컴포넌트의 "상태를 변경하는 함수" 그 자체를 하위 컴포넌트로 전달하고, 이 함수를 하위 컴포넌트가 실행한다. 이것을 상태 끌어올리기라고 한다
side Effect(부수효과)
- 함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 경우 해당 함수는 Side Effect가 있다고 이야기합니다.
let foo = 'hello'; function bar() { foo = 'world'; } bar(); // bar는 Side Effect를 발생시킵니다!
Pure Function(순수 함수)
- 순수 함수란, 오직 함수의 입력만이 함수의 결과에 영향을 주는 함수를 의미합니다. 함수의 입력이 아닌 다른 값이 함수의 결과에 영향을 미치는 경우, 순수 함수라고 부를 수 없습니다. 또한 순수 함수는, 입력으로 전달된 값을 수정하지 않습니다.
- 순수 함수에는 네트워크 요청과 같은 Side Effect가 없습니다.
- 어떠한 전달 인자가 주어질 경우, 항상 똑같은 값이 리턴됨을 보장합니다. 그래서 예측 가능한 함수이기도 합니다.
function upper(str) { return str.toUpperCase(); // toUpperCase 메소드는 원본을 수정하지 않습니다 (Immutable) } upper('hello') // 'HELLO'
React의 함수 컴포넌트
- 우리가 앞서 배운 React의 함수 컴포넌트는, props가 입력으로, JSX Element가 출력으로 나갑니다. 여기에는 그 어떤 Side Effect도 없으며, 순수 함수로 작동합니다
function SingleTweet({ writer, body, createdAt }) { return <div> <div>{writer}</div> <div>{createdAt}</div> <div>{body}</div> </div> }
- 하지만 보통 React 애플리케이션을 작성할 때에는, AJAX 요청이 필요하거나, LocalStorage 또는 타이머와 같은 React와 상관없는 API를 사용하는 경우가 발생할 수 있습니다. 또 어떤 이벤트로인해 side Effect를 만드는 경우도 있습니다
- React는 Side Effect를 다루기 위한 Hook인 Effect Hook을 제공합니다.
Effect Hook
- useEffect는 컴포넌트 내에서 Side effect를 처리할 수 있게 하는 Hook 입니다.(import해 쓰면 됨)
- useEffect의 첫 번째 인자는 함수입니다. 해당 함수 내에서 side effect를 실행하면 됩니다.
- useEffect는 1)컴포넌트 생성후 처음 화면 렌더링시 ,2)컴포넌트에 새로은 props가 전달되며 렌더링시,3)컴포넌트에 상태가 바뀌며 렌더링시 실행된다
- 최상위에서만 Hook을 호출해야합니다
- React 함수 내에서 Hook을 호출합니다.
1.조건부 side effectc 처리하기
useEffect(함수, [종속성1, 종속성2, ...])
- 배열 내의 어떤 값이 변할 때에만, (effect가 발생하는) 함수가 실행됩니다
- ajax요청으로 어떤값이 변할때마다 처리해야하는 side effect를 처리할떄 사용
2.단 한 번만 실행되는 Effect 함수
useEffect(함수, [])
- 컴포넌트가 처음 생성될 때만 effect 함수가 실행됩니다.
- 대표적으로 처음 단 한 번, 외부 API를 통해 리소스를 받아오고 더 이상 API 호출이 필요하지 않을 때에 사용할 수 있습니다.