[javascript] React useEffect로 로딩 함수를 한 번만 호출하는 방법

useEffect는 훅이 모든 변화 기능에 전달 실행할 반응한다. 원하는 속성이 변경 될 때만 호출되도록 최적화 할 수 있습니다.

초기화 함수를 componentDidMount호출하고 변경시 다시 호출하지 않으 려면 어떻게해야 합니까? 엔터티를로드하려고하지만로드 기능에 구성 요소의 데이터가 필요하지 않다고 가정 해 봅시다. useEffect후크를 사용하여 어떻게 만들 수 있습니까?

class MyComponent extends React.PureComponent {
    componentDidMount() {
        loadDataOnlyOnce();
    }
    render() { ... }
}

후크를 사용하면 다음과 같이 보일 수 있습니다.

function MyComponent() {
    useEffect(() => {
        loadDataOnlyOnce(); // this will fire on every change :(
    }, [...???]);
    return (...);
}



답변

useEffect초기 렌더링 이후에
제공된 함수 만 실행하려면 빈 배열을 두 번째 인수로 제공 할 수 있습니다.

function MyComponent() {
  useEffect(() => {
    loadDataOnlyOnce();
  }, []);

  return <div> {/* ... */} </div>;
}


답변

TL; DR

useEffect(yourCallback, []) -첫 번째 렌더링 후에 만 ​​콜백을 트리거합니다.

상해

useEffect구성 요소를 렌더링 할 때마다 기본적으로 실행 되므로 효과가 발생합니다.

useEffect컴포넌트에 배치 할 때 리 액트 에 콜백을 실행하고 싶다고 말합니다. 렌더링은 렌더링 후 및 DOM 업데이트를 수행 한 후 효과를 실행합니다.

콜백 만 전달하면 각 렌더링 후에 콜백이 실행됩니다.

두 번째 인수 (배열)를 전달하면 React는 첫 번째 렌더링 후와 배열의 요소 중 하나가 변경 될 때마다 콜백을 실행합니다. 예를 들어 배치 할 때 useEffect(() => console.log('hello'), [someVar, someOtherVar])-콜백은 첫 번째 렌더링 후 someVar또는 그 중 하나 someOtherVar가 변경 되거나 렌더링 된 후에 실행됩니다 .

두 번째 인수에 빈 배열을 전달하면 React는 각 배열을 렌더링 한 후 비교하고 아무것도 변경되지 않았으므로 첫 번째 렌더링 후에 만 ​​콜백을 호출합니다.


답변

useMountEffect 훅

컴포넌트 마운트 후 한 번만 함수를 실행하는 것은 구현 세부 사항을 숨기는 자체 후크를 정당화하는 일반적인 패턴입니다.

const useMountEffect = (fun) => useEffect(fun, [])

모든 기능적 구성 요소에서 사용하십시오.

function MyComponent() {
    useMountEffect(function) // function will run only once after it has mounted. 
    return <div>...</div>;
}

useMountEffect 후크 정보

useEffect두 번째 배열 인수와 함께 사용하면 React는 마운트 후 (초기 렌더링) 및 배열의 ​​값이 변경된 후 콜백을 실행합니다. 빈 배열을 전달하므로 마운트 후에 만 ​​실행됩니다.


답변

빈 배열을에 두 번째 인수로 전달하십시오 useEffect. 이것은 효과적으로 React에게 문서를 인용하여 알려줍니다 .

이것은 React에게 효과가 props 또는 state의 값에 의존하지 않으므로 다시 실행할 필요가 없다는 것을 나타냅니다.

다음은 작동한다는 것을 보여주기 위해 실행할 수있는 스 니펫입니다.

function App() {
  const [user, setUser] = React.useState(null);

  React.useEffect(() => {
    fetch('https://randomuser.me/api/')
      .then(results => results.json())
      .then(data => {
        setUser(data.results[0]);
      });
  }, []); // Pass empty array to only run once on mount.

  return <div>
    {user ? user.name.first : 'Loading...'}
  </div>;
}

ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>


답변

mount함수 를 정의하고 싶습니다. EsLint를 같은 방식으로 속이고 useMount더 자명하다고 생각합니다.

const mount = () => {
  console.log('mounted')
  // ...

  const unmount = () => {
    console.log('unmounted')
    // ...
  }
  return unmount
}
useEffect(mount, [])


답변

트릭은 useEffect가 두 번째 매개 변수를 사용한다는 것입니다.

두 번째 매개 변수는 다시 렌더링하기 전에 구성 요소가 변경되었는지 확인하는 변수의 배열입니다. 여기에 확인하기 위해 원하는 소품과 상태를 넣을 수 있습니다.

또는 아무것도 넣지 마십시오.

import React, { useEffect } from 'react';

function App() {
  useEffect(() => {

    // Run! Like go get some data from an API.

  }, []); //Empty array as second argument

  return (
    <div>
      {/* Do something with data. */}
    </div>
  );
}

그러면 useEffect가 한 번만 실행됩니다.

문서에서 참고하십시오.

이 최적화를 사용하는 경우 시간이 지남에 따라 변경되고 효과에 사용되는 구성 요소 범위 (예 : 소품 및 상태)의 모든 값이 배열에 포함되어 있는지 확인하십시오. 그렇지 않으면 코드에서 이전 렌더링의 오래된 값을 참조합니다.


답변