Side-Effect 가 뭐지? ( React )

9064 단어 ReactReact


아아.. 오늘 나는 Side-Effect 가 무엇인지 알고싶어졌다..

그럼 바로 시작.

Side-Effect?

Side-Effect가 뭘까?

우선 정의부터 알아보자.

위키백과에서는 Side-Effect 를 다음과 같이 정의하고있다. (부작용?)

부작용
컴퓨터 과학에서 함수가 결과값 이외에 다른 상태를 변경시킬 때 부작용이 있다고 말한다. 예를 들어, 함수가 전역변수나 정적변수를 수정하거나, 인자로 넘어온 것들 중 하나를 변경하거나 화면이나 파일에 데이터를 쓰거나, 다른 부작용이 있는 함수에서 데이터를 읽어오는 경우가 있다.

부작용이라... 우리가 보통 부작용이라는 말을 어떨때 사용하는가?
의도치 않은 작용이 일어났을때 부작용이라고 하지 않는가?

두통약을 먹었는데, 먹고나니깐 배가 아파진다거나.. (해로운 부작용)
김치를 먹었는데 갑자기 몸살감기가 나아버린다던가.. (말도안되는 이로운 부작용)
이런식으로 부작용을 나타내는데
Side-Effect 는 반드시 해로운 영향만 끼치는것은 아니다! (말도 안되는 김치 비유처럼..)

어쨌든 Side-Effect사용하는 곳에 따라 다양한 의미를 가지고 있지만 일반적으로 "의도치 않은 결과" 를 의미한다!

그리고 오늘은 리액트에서 Side-Effect 가 의미하는게 무엇인지 알아 볼 것이다!

예시

Side-Effect 의 예시

리액트에서의 Side-Effect 예시를 한번 살펴보자.

리액트에서 Side-Effect 는 다음과 같이 정의한다!

함수가 실행되면서 함수 외부에 존재하는 값이나 상태를 변경시키는 등의 행위를 말합니다. 예를들어 함수에서 전역변수의 값을 변경하거나 혹은 함수 외부에 존재하는 버튼의 텍스트를 변경하거나, 파일을 쓰거나, 쿠키 저장, 네트워크를 통해 데이터를 송신하는 것 등이 있습니다.

Side-Effect 코드

function UserProfile({ name }) {
  const message = `${name}님 환영합니다!`; //함수 반환 값 생성

  // Bad!
  document.title = `${name}의 개인정보`; //함수 외부와 상호작용하는 Side-effect 코드
  return <div>{message}</div>;
}

이것이 Side-Effect 코드다!
근데 이게 왜 Side-Effect 코드일까?
우리가 봐야 할 부분은 document.title 부분이다!

주석으로 달려있듯 이 컴포넌트는 Side-Effect 코드이다.

이게 왜 Side-Effect 코드냐면, 함수가 매개변수를 받아 결과를 생성하는 것과 무관한 행동을 하고있기 때문이다!
(나중에 이런 일관성없는 코드들이 쌓이게되면 코드가 많이 복잡해지겠지..?)

내가 느끼기에 리액트에서 Side-Effect 를 발생시키는 함수는 오지랖이 넓은 함수 같다.

근데 이 Side-Effect 라는게 꼭 나쁜것만은 아니지만, 코드를 알아보기 어렵게하고 개발비용을 증가시키다보니 리액트같은 "선언형 프로그래밍" 에서는 Side-Effect 를 최소화 하는 방향으로 변하고 있다고한다.

만약 위의 document.title 코드가 좀 더 무거운 작업을 하는 코드라면 컴포넌트가 렌더링 될 때 마다 프로그램을 지연시키게 될 것이다.

개발자는 React가 컴포넌트를 다시 렌더링하는 시점을 정확하게 통제하기 어렵기 때문에 React가 다시 렌더링할 때마다 발생하는 프로그램의 지연 원인을 찾느라 고생하게 될 것이다!

Side-Effect 처리

그러면 리액트에서는 Side-Effect 를 어떻게 처리할까?

리액트는 Side-Effect 작업을 분리할 수 있도록 useEffect Hook을 지원한다.

그러면 useEffect를 이용해서 어떻게 처리할까?

function UserProfile({ name }) {
  const message = `${name}님 환영합니다!`;

  //Side-Effect 코드를 UseEffect로 분리
  useEffect(() => {
    document.title = `${name}의 개인정보`; 
  }, [name]);
  return <div>{message}</div>;
}

바로 이렇게 처리할 수 있다!

useEffect() 를 이용하여 이렇게 Side-Effect 작업을 분리시켜놓으면, 우리가 원하는 적절한 시점에 Side-Effect 작업을 수행할 수 있도록 해줄 수 있다.

이러한 처리는 함수형 컴포넌트가 빠르게 렌더링 될 수 있게 도와주며, 프로그램을 복잡하게 만드는 Side-Effect 영역을 함수와 분리할 수 있게 도와준다!

이렇게 분리시켜놓으면, 어떤 개발자라도 컴포넌트에 Side-Effect 가 포함된다는 것을 알 수 있다.
또한 React에서는 useEffect()에 등록된 Side-Effect 코드를 최적화된 시점에 실행하기 때문에 컴포넌트의 실행속도를 개선하는데도 도움이 될 것이다!


마무리

이번 글에서 리액트에서 Side-Effect 가 무엇인지, 또 어떻게 처리하는지를 정리했다.

Side-Effect 가 되게 여러 곳에서 다양한 의미로 쓰이는것같다.

오늘 정리하면서 여러군데 찾아봤는데 Side-Effect 가 "의도치 하지 않은 효과" 를 발생시킨다는 개념은 어디든지 비슷했지만, 이를 처리하는 방식들이 다른것같았다.

그리고 useEffect()Side-Effect 를 처리하기 위해 지원하는 Hook 이라는 사실도 오늘 처음알게 되었다.

평소에 useEffect() 를 API에서 데이터를 받아온 후 state를 바꿔서 리렌더링 할 때 사용하거나 componentDidMountcomponentDidUpdate, componentWillUnmount 와 같은 생명주기 메소드를 대신하는 용도로 사용했었는데 useEffect()Side-Effect 를 처리하기 위해 제공하는 메소드라는걸 알게되었다.

그리고 내가 충격받은건 알고보니 API에서 데이터를 받아오는 행위도 Side-Effect 였다!!

어쩌면 useEffect()를 이용하여 처리하는 대부분이 Side-Effect 일수도..?

리액트 공식문서에 언급된 부분 👇👇👇

https://ko.reactjs.org/docs/hooks-effect.html

Side-Effect 하나를 가볍게 알아보려고 했을 뿐인데 다른 지식들도 습득하게 된 것 같다.

이것도 Side-Effect 일려나? ㅋ

참고
https://points.tistory.com/86
https://www.inflearn.com/questions/12660
https://ko.reactjs.org/docs/hooks-effect.html

좋은 웹페이지 즐겨찾기