Computer/Front-end

무한 렌더링 현상 막기 - Axios로 받은 데이터 '1회만' state에 set하기 (useEffect 활용)

madnaeun 2023. 6. 21. 17:51
axios로 데이터를 불러와 table.js 에서 사용하려고 했는데 이상하게 무한으로 렌더링 되서 서버에 지속적으로 데이터 요청하는 문제가 발생함
const [msg, setMsg] = useState([]);
  UserService.getTableData()
  .then((res) => {
		setMsg(res.data);
})

문제 발생 이유

useState hook 으로 상태를 관리할 때, 상태가 변경되면 컴포넌트가 다시 렌더링이 되는 특징이 있음. 때문에 위의 코드에서 **setMsg**를 호출하면 상태가 변경되어 다시 렌더링이 일어나고, 다시 **setMsg**가 호출되면 이 과정이 반복되어 무한 렌더링 현상이 발생함.


해결 방안(https://citronbanana.tistory.com/110 참고)

useEffect를 이용한 초기화 :useEffect의 기본 동작은 모든 렌더링이 완료된 후 첫 번째 인자(Parameter)로 전달한 콜백(Callback) 함수가 실행되는 것이다. 그런데 전달한 콜백 함수에 setState가 포함되면 다시 렌더링하게 될 것이고, 또 다시 콜백 함수가 실행되며 무한 렌더링 문제가 발생한다.
 이를 방지하기 위해 useEffect의 두 번째 인자로 빈 배열([ ], Empty array)을 전달해 해결할 수 있다. 원래는 배열에 관찰하고 싶은 특정 변수(props, state)를 담아 해당 변수가 변경될때만 콜백이 실행될 수 있도록 하는 '조건부 useEffect'로 사용된다. 하지만 빈 배열([ ])을 전달하면 관찰 대상이 없으므로 최초 1회만 콜백 함수가 실행되고 그 뒤로 다시 실행되지 않는다.

Event(버튼 클릭) 기반 일회성 작동: Event 기반 setState를 한다면 무한 렌더링을 피해갈 수 있다. 단 이 방법은 버튼 클릭과 같은 이벤트가 발생해야 한다는 조건 때문에 이전 컴포넌트(Previous Page)에서 데이터를 요청해야 한다.

➡️ 로그인을 하고 바로 게시판을 보는 식으로 구성되어있어 이전 페이지에서 데이터를 요청할 수 없다. 그래서 1번의 방식으로 코드를 수정함.

useEffect(() => {    
    UserService.getTableData()
    .then(response => {
      setMsg(response.data);
    })    
  }, []);