콜백으로 효과를 사용하지 마십시오!

React의 useEffect 후크는 때때로 이해하기 쉽지 않습니다. 제대로 작동하기 어려울 수 있습니다. 누락된 종속성이 있거나 오래된 클로저 또는 무한 루프가 발생할 수 있습니다.

이 블로그 게시물에서는 useEffect 후크의 일반적인 오용에 대해 살펴보겠습니다. 오류가 발생하지는 않지만 불필요한 재렌더링과 코드 복잡성이 발생합니다. useEffect가 기본적으로 콜백인 두 가지 예와 이와 같은 코드를 단순화하는 방법을 살펴보겠습니다.

1. 콜백을 트리거하는 상태 업데이트



이것은 상태 업데이트가 콜백을 트리거하는 간단한 예제 구성 요소입니다. 물론 분해된 부품입니다. 그러나 나는 실제 코드의 더 복잡한 구성 요소에서 이 패턴을 충분히 자주 보았습니다.

function Form({ onUpdate }) {
  const [email, setEmail] = useState('');
  const firstRender = useRef(true);

  useEffect(() => {
    if (firstRender.current) {
      firstRender.current = false;
      return;
    }
    onUpdate(email);
  }, [onUpdate, email]);

  return (
    <form>
      <input
        value={email}
        onChange={(e) => setEmail(() => e.target.value)}
        name="email"
      />
    </form>
  );
}


양식 안에 입력이 있습니다. 구성 요소는 상태 변수의 email 값을 추적합니다. onUpdate가 변경될 때마다 email 소품이 호출되기를 원합니다.

한 가지 옵션은 위의 예와 같이 useEffect를 종속성으로 사용하여 email하는 것입니다. 이 접근 방식에는 두 가지 문제가 있습니다.
  • 입력 구성 요소의 핸들러onChange와 부모가 이 구성 요소에 전달한 소품onUpdate 간의 연결을 난독화합니다.
  • 첫 번째 렌더링에서 useRef 호출을 방지하려면 onUpdate로 해결 방법이 필요합니다.

  • Note: There is a very valid use-case though that I missed in my first version. In some cases, you might want the onUpdate function only to be called after the state has been set, similar to using the second parameter of a class component's this.setState(state, callback). In this case, useEffect is the way to go, in fact.



    다른 접근 방식은 매우 간단합니다. 대신 함수를 사용합니다.

    function Form({ onUpdate }) {
      const [email, setEmail] = useState('');
    
      const onChange = (e) => {
        const { value } = e.target;
        setEmail(value);
        onUpdate(value);
      };
    
      return (
        <form>
          <input
            value={email}
            onChange={onChange}
            name="email"
          />
        </form>
      );
    }
    


    이제 setEmailonUpdate가 함께 결합되어 있다는 것이 즉시 분명해집니다. useRef 도 제거했습니다.

    제 생각에는 훨씬 깨끗하고 이해하기 쉽습니다.

    2. 데이터 변환



    불필요한 경우useEffect의 또 다른 일반적인 예는 다시 상태 업데이트와 관련이 있습니다. 이번에는 데이터를 변환하는 데 사용됩니다.

    다음 예를 살펴보십시오.

    I took this example from a new course about becoming job-ready for working in professional dev teams. Check it out if you're interested, I'll launch it soon.



    function RedditPosts() {
      const [data, setData] = useState(null);
      const [posts, setPosts] = useState([]);
    
      useEffect(() => {
        fetch('https://www.reddit.com/r/javascript/top.json?t=day&limit=10')
          .then(response => response.json())
          .then(({ data }) => setData(data));
      }, []);
    
      useEffect(() => {
        if (!data) {
          return;
        }
    
        const mappedPosts = data.children.map(post => post.data);
        setPosts(mappedPosts);
      }, [data]);
    
      return (
        <div>
          {
            posts.map(post => (
              <div key={post.id}>{post.title}</div>
            ))
          }
        </div>
      );
    }
    


    그래서 여기서 무슨 일이 일어나고 있습니까? 2개useEffect가 있습니다. 첫 번째는 구성 요소가 마운트되었을 때 트리거됩니다. API에서 데이터를 가져와 상태 변수에 저장합니다.

    그리고 두 번째useEffect는 어떻습니까? data 상태가 업데이트되면 트리거됩니다. 데이터 개체를 게시물 배열로 변환하여 렌더링을 준비합니다. 그리고 다시 첫 번째 렌더링에서 효과를 실행하지 않는 해결 방법이 필요합니다: !data 에 대한 확인.

    대체 접근 방식은 어떻게 생겼습니까? data 상태를 완전히 제거하고 API 요청 후 변환을 처리할 수 있습니다.

    이것이 어떻게 생겼는지입니다.

    function RedditPosts() {
      const [posts, setPosts] = useState([]);
    
      useEffect(() => {
        fetch('https://www.reddit.com/r/javascript/top.json?t=day&limit=10')
          .then(response => response.json())
          .then(({ data }) => data.children.map(post => post.data))
          .then((mappedPosts) => setPosts(mappedPosts));
      }, []);
    
      return (
        <div>
          {
            posts.map(post => (
              <div key={post.id}>{post.title}</div>
            ))
          }
        </div>
      );
    }
    


    두 번째useEffect를 제거하고 API 요청과 함께 첫 번째 변환을 처리합니다.

    훨씬 간단합니다!

    포장하기



    물론 useEffect 에 대한 유효한 사용 사례가 많이 있지만 이 두 가지는 여기에 포함되지 않습니다. 위의 방법 중 하나로 useEffect를 사용하는 자신을 인식했다면 잠시 멈추고 다음에 가능한 대안을 생각해 보십시오.

    이 블로그 게시물이 마음에 들었고 업데이트를 받고 싶다면subscribe to my list .

    현재 또는 가까운 장래에 웹 개발 작업을 찾고 있다면 이 무료 과정이 흥미로울 수 있습니다.

    개발 작업을 얻을 기회를 높이십시오



    소프트웨어 개발자로서 첫 직장을 찾는 것은 어려울 수 있습니다. 답장도 없이 수십 번 신청할 수 있습니다.

    당신이 그 상황에 있다면 내 무료 과정을 확인하십시오. 커튼 뒤의 고용 프로세스에 대한 귀중한 통찰력, 이력서를 최적화하는 방법, 뛰어난 포트폴리오 프로젝트를 만드는 방법 및 면접에 대한 많은 팁을 통해 많은 지원자 중에서 눈에 띄는 방법을 배우게 됩니다.

    좋은 웹페이지 즐겨찾기