1. 코드 상황과 해결
import Axios from "axios";
import React, { useState, useEffect } from "react";
type Device = {
DEVICE_ID: number;
DEVICE_NAME: string;
};
function Devices({ DEVICE_ID, DEVICE_NAME }: { DEVICE_ID: number; DEVICE_NAME: string; }) {
function checkId() {
console.log(DEVICE_ID);
}
return (
<tr onClick={checkId}>
<td>{DEVICE_ID}</td>
<td>{DEVICE_NAME}</td>
</tr>
);
}
export function getList(){
// eslint-disable-next-line react-hooks/rules-of-hooks
const [devicesList, setDevicesList] = useState<Device[]>([]);
// eslint-disable-next-line react-hooks/rules-of-hooks
useEffect(() => {
Axios.get("http://localhost:8000/devices/list", {})
.then((res) => {
const { data } = res;
setDevicesList(data);
})
.catch((e) => {
console.error(e);
})
}, [])
return devicesList.map((v: Device) => {
return (
<Devices
DEVICE_ID={v.DEVICE_ID}
DEVICE_NAME={v.DEVICE_NAME}
></Devices>
);
})
}
- 위 코드에서 주석이 없다면 useState와 useEffect에서 에러가 발생한다
// eslint-disable-next-line react-hooks/rules-of-hooks
2. 근원적인 해결 방법과 원인
- eslint는 컨벤션이지만 컨벤션에 어긋나는 경우에는 에러를 발생시킨다. 실제로 기능적 에러가 나는 것은 아니다.
- 위와 같이 getList() 함수라고 명명되어 있다면 소문자로 시작하기 때문에 hook은 컴포넌트 최상위 단계에서 수행한다고 판단하지 않아서 오류가 발생한 것이다.
- 최상위란 반복문, 조건문 중첩된 함수 내에서 호출하지 않는 것을 의미한다.
- 이 경우 동일한 순서로 훅을 호출하는 것이 보장 되지 않기 때문이다.
- 해결 방법
- 아래와 같이 함수 이름을 바꿔준다. 아래와 같이 use를 붙이거나 GetList()처럼 대문자로 시작해도 해결된다.
export function useGetList
3. 참조
1. React: exhustive-deps Eslint 규칙 이해하기 : https://velog.io/@2pandi/React-exhustive-deps-Eslint-%EA%B7%9C%EC%B9%99-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0