출처: https://www.youtube.com/watch?v=-IqIqJxC-wo
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 : Sharable app location
- Web storage : Persist between sessions, one brower
- Local State : Only one component needs the state
- Lifted state : A few related components need the state
- Derived state : State can be derived from existing state
- Refs : DOM reference, state that isn’t rendered
- Context : Global or subtree state
- Third party library : Global state, Remote state
내가 본 가장 흔한 실수 중 하나는 URL을 잃어버리는 것입니다. 가장 좋은 방법은 URL을 다른 사람과 공유하면 내가 지금 보고 있는 것과 동일한 것을 볼 수 있을지 스스로 물어보는 것입니다.
refs를 사용하려면 refs는 상태를 보유할 수 있으며 refs는 실행 취소와 같은 작업에도 유용하므로 백그라운드에서 보관하고 싶은 항목이며 refs를 렌더링하고 싶지 않은 변수는 컨텍스트를 고려 하는 도구이다.
글로벌 상태 또는 글로벌 기능이 있고 마지막으로 제 3자 라이브러리가 글로벌 상태 또는 원격 상태와 같은 특정 유형의 상태에 훌륭하다면 원격 상태는 React Query, SWR, RTK 쿼리 등과 같은 도구를 사용하여 서버에서 가져온 상태를 의미합니다.
이번 내용을 정리하면서 React에서 자주하는 실수들을 되돌아보게 되었습니다. 코드를 작성하는 것은 습관에서 나온다고 생각하는 편이라 좋은 습관을 가질 수 있도록 조금 더 생각을 하고 간편하게 동작하는 코드를 작성하도록 노력해야겠다고 생각했습니다.
'Front-End' 카테고리의 다른 글
React-Native - The Basics (1) | 2024.03.17 |
---|---|
React-Native에 대해서 알아보자! (0) | 2024.02.17 |
Next.js Project Structure (1) | 2024.02.03 |
2024년 상태 관리의 종결 : zustand (0) | 2024.01.19 |
Virtualize List with react-window (2) | 2023.12.17 |