함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 경우,
해당 함수는 Side Effect가 있다고 얘기 한다.
Side Effect 코드 예제
let foo = 'hello'; // foo라는 전역 변수 <br> function bar() { foo = 'world'; // 전역 변수 foo에 영향을 준다 } <br> bar(); // bar는 Side Effect를 발생시킴!
순수 함수란,
오직 함수의 입력만이 함수의 결과에 영향을 주는 함수를 의미한다.
함수의 입력이 아닌 다른 값이 함수의 결과에 영향을 미치는 경우, 순수 함수라고 부를 수 없다. 또한 순수 함수는, 입력으로 전달된 값을 수정하지 않는다.
Pure Function 코드 예제
function upper(str) { return str.toUpperCase(); // toUpperCase 메소드는 원본을 수정하지 않음. (Immutable) } <br> upper('hello') // 'HELLO'
React 애플리케이션을 작성할 때,
AJAX 요청이 필요하거나, LocalStorage 또는 타이머와 같은 React와 상관없는 API를 사용하는 경우 React의 입장에서는 전부 Side Effect 이다.
React는 Side Effect를 다루기 위한 Hook인 Effect Hook을 제공한다.
Effect Hook (useEffect) 코드 예제
import { useEffect, useState } from "react"; import "./styles.css"; import { getProverbs } from "./storageUtil"; <br> export default function App() { const [proverbs, setProverbs] = useState([]); const [filter, setFilter] = useState(""); const [count, setCount] = useState(0); <br> useEffect(() => { // Effect Hook const result = getProverbs(filter); setProverbs(result); }, [filter]); <br> const handleChange = (e) => { setFilter(e.target.value); }; <br> const handleCounterClick = () => { setCount(count + 1); }; <br> return ( <div className="App"> 필터 <input type="text" value={filter} onChange={handleChange} /> <ul> {proverbs.map((prvb, i) => ( <Proverb saying={prvb} key={i} /> ))} </ul> <button onClick={handleCounterClick}>카운터 값: {count}</button> </div> ); } <br> function Proverb({ saying }) { return <li>{saying}</li>; }
useEffect의 첫번째 인자는 함수다.
해당 함수 내에서 side effect를 실행하면 되는데, 이 함수는 다음과 같은 조건에서 실행된다.
Side Effect 기본 실행 조건
1. 컴포넌트 생성 후 처음 화면에 렌더링 될 때.
2. 컴포넌트에 새로운 props가 전달되며 렌더링 될 때.
3. 컴포넌트에 상태(state)가 바뀌며 렌더링 될 때.
위 예제 코드처럼 두 번째 인자로 [filter]가 들어갔는데,
이는 조건부 실행이다.
Side Effect 조건부 실행 조건
1. 두 번째 인자에 아무것도 입력을 안하면 기본 실행 조건과 동일.
2. 두 번째 인자에 빈배열이 들어가면 컴포넌트가 처음 생성될 때만 실행.
3. 세 번째 인자에 특정 배열이 들어가면 해당 컴포넌트가 변할 때만 실행.
Hook 쓸 때 주의할 점
1. 최상위에서만 Hook을 호출한다.
2. React 함수 내에서 Hook을 호출한다.