Mistake : Separating related state
Solution : Unify related state
코드를 분리할 때 가장 일반적으로 볼 수 있는 것 중 하나인 관심사를 분리하는 것부터 시작합니다. 해답은 매우 간단하며, 즉 관련된 상태에 대해 이야기 할 때 관심사가 같은 상태를 통합하는 것입니다. 여기서 개념은 속성이 서로 관련되어 서로 적용되는 상태에 대해 생각하는 것 입니다.
function App() {
const [address, setAddress] = useState("");
const [city, setCity] = useState("");
const [country, setCountry] = useState("");
return <p>Hi</p>
}
위 처럼 이 상태를 서버에 저장하려고 할 때 할 일은 주소를 보내기 위해 하나의 HTTP 호출을 보내는 것입니다. 주소는 address
, city
, country
로 구성되어 있습니다. 여기서 세 개의 상태를 갖는 대신 한 개의 상태만 가져보는 것은 어떨까요?
function App() {
const [address, setAddress] = useState({
name: "",
city: "",
country: "",
});
return <p>Hi</p>
}
상태를 이렇게 통합하면 상태를 적게 호출 할 수 있고, 초기화 할 때 간단하다는 장점이 있습니다. 서버의 데이터로 채워질 양식이라고 상상해보세요. State를 서버로 다시 보낼 때 하나의 객체로 만들어 서버로 보내고 싶을 것이기 때문입니다.
첫번째 교훈은 상태를 관심사에 맞게 그룹화 시키는 것입니다.
Mistake : Multiple useState calls in a row
Solution : Unify. Consider useReducer.
두번째 교훈은 연속적으로 여러 개의 useState
를 호출할 때 조심하라는 것입니다.
이런 일을 보면 더욱 상태를 잘 통합해야 합니다. 그리고 useReducer
를 고려해야 한다는 신호입니다. 최근에 트위터에서 설문 조사를 했는데 응답한 수 천명의 React 개발자 중 절반은 말 그대로 useReducer
를 사용한 적이 없다고 합니다. useReducer
는 실제로 놀라운 hook입니다. 사람들인 이 기능을 종종 잊어버리기 때문에 더 많이 사용하는 것을 권하고 싶습니다.
useReducer
에서 가장 좋았던 것은 상태를 보호하는 것입니다. 내가 수신한 payload
가 우리가 기대한 것인지 확인하기 위해 여기서 일종의 논리를 수행하고 상태를 설정하게 됩니다.
useReducer
는 상태를 보호합니다. useState
는 자체적으로 보호하지 않습니다. 언제든지 setter를 호출할 수 있습니다. useReducer
를 사용하면 여러 개의 setState
를 피할 수 있습니다. 이를 통해 set이 잘 되고 있음을 알 수 있습니다. useReducer를 사용하면 하나 이상을 업데이트 할 수 있습니다.
setState
가 연속적으로 여러 번 호출되는 것을 보고 상태가 관련이 있는 경우, 상태를 통합해야 하거나 useReducer
를 고려해야 한다고 생각하게 만듭니다.
Mistake : Syncing state in useEffect
Solution : Derive state
가끔 useEffect를 이용하여 상태를 변경하는 것을 볼 수 있다. 이 문제는 불필요하다는 것이다.
이는 모두 불필요한 상태의 신호이다. 일반적으로 대신 수행할 수 있는 작업은 Derive state(상태 파생)이다. React 개발자에게 충분히 활용되지 않는 방법이기도 하다.
function App() {
const [firstName, setFirstName] = useState("John");
const [lastName, setLastName] = useState("Doe");
const [fullName, setFullName] = useState("John Doe")
useEffect(() => {
setFullName(`${firstName}` `${lastName}`);
}, [firstName, lastName])
return <p>Hi</p>
}
위 처럼 만드는 것은 매우 어리석은 일이다. 더 많은 State가 생기면 쉽게 실수를 저지를 수 있으며 우리가 Value를 파생시킬 수 있다는 것을 깨닫지 못합니다. 따라서 기존 상태에서 필요한 값을 파생시킬 수 있는지 세심한 주의를 기울이는 것이다.
해결책은 useEffect를 선언조차 하지 않고 만들 수 있습니다.
function App() {
const [firstName, setFirstName] = useState("John");
const [lastName, setLastName] = useState("Doe");
// const [fullName, setFullName] = useState("John Doe")
// useEffect(() => {
// setFullName(`${firstName}` `${lastName}`);
// }, [firstName, lastName])
const fullname = firstName + " " + lastName;
return <p>Hi</p>
}
값을 알고 어떤 필드 가 필요한 지 알고 나면 다음을 수행할 수 있습니다. 실제도 모든 렌더링에서 어떤 유효성 검사 오류가 발생하는지 계산한 다음 양식 자체의 상태를 기반으로 오류를 표시할지 여부를 결정합니다.
Mistake : Fetching in useEffect
Solution : React query, RSC, swr, Apollo, loader
useEffect를 통해 data fetcing을 하지 않기.
우리는 오래 전에 Well Hooks가 출시된 이후, Use In Effect를 가져왔고 그 전에는 컴포넌트에서 Mount를 수행하는 것이 실수라고 생각합니다. React 개발자는 지금 추상화를 사용해야 할 것입니다. 우리가 사용하지 못하는 장점을 제공합니다. useEffect
는 잘못하기가 너무 쉽고 정말 중요한 여러가지 사항을 잊어버리기 쉽다는 것입니다.
React Query
가 우리에게 제공하는 것이 무엇인지 생각해보세요. 이는 Loading State, Error Handling, Data, Refetching, Cache 등 이전에 가져온 데이터를 즉시 할 수 있습니다. 키를 사용해 캐시를 지울 수도 있고, 탭으로 이동하면 다시 가져올 수 있다. 그렇기 때문에 React Query
나 SWR
과 같은 도구가 매우 매력적입니다.
여기서 강조하고 싶은 것은 작성해야 할 코드가 훨씬 적다는 점을 가지고 있다.
우리가 사용하고 싶은 것은 코드를 가져와서 축소하는 일종의 추상화입니다. 앞서 본 세 가지 다른 상태(loading, error, data)를 선언해야 하며 이 모든 것을 처리하기 위한 논리가 여기에 있어야 하므로 사용자 정의 Hooks를 사용하면 코드가 많이 줄어듭니다.
React 개발자를 위한 핵심을 약하면 다음과 같다.
내가 본 가장 흔한 실수 중 하나는 URL을 잃어버리는 것입니다. 가장 좋은 방법은 URL을 다른 사람과 공유하면 내가 지금 보고 있는 것과 동일한 것을 볼 수 있을지 스스로 물어보는 것입니다.
refs
를 사용하려면 refs
는 상태를 보유할 수 있으며 refs
는 실행 취소와 같은 작업에도 유용하므로 백그라운드에서 보관하고 싶은 항목이며 refs
를 렌더링하고 싶지 않은 변수는 컨텍스트를 고려 하는 도구이다.
글로벌 상태 또는 글로벌 기능이 있고 마지막으로 제 3자 라이브러리가 글로벌 상태 또는 원격 상태와 같은 특정 유형의 상태에 훌륭하다면 원격 상태는 React Query
, SWR
, RTK Query
등과 같은 도구를 사용하여 서버에서 가져온 상태를 의미합니다.