728x90
1. 꼭 써봐야 하는 10가지 리액트 커뮤니티 훅들
- react-hook-form 라이브러리의 useForm : 간단한 코드로 입력값 검증하고 에러처리 가능
- react-use 라이브러리의 useUpdateEffect : 특정 상태가 업데이트 될 때 함수 호출 가능
import { useUpdateEffect } from "react-use"
const Home = () => {
useUpdateEffect(() => {
// 이 함수는 첫 렌더링에 실행되지 않습니다
console.log("Runs only if the state updates")
}, [fName])
return ( ...)
}
- react-use 라이브러리의 useCopyToClipboard : 상태(사용자가 클립보드에 복사하는 문자열 값)와, 상태를 업데이트하고 클립보드에 복사하는 함수 반환
import { useCopyToClipboard } from "react-use";
const App = () => {
const [text, setText] = useState("");
const [state, copyToClipboard] = useCopyToClipboard();
return (
<div>
<input value={text} onChange={(e) => setText(e.target.value)} />
<button type="button" onClick={() => copyToClipboard(text)}>
copy text
</button>
</div>
);
};
- react-use 라이브러리의 useLocalStotage : 로컬 스토리지 손쉽게 접근 가능
import { useLocalStorage } from "react-use";
export default function App() {
const [token, setToken, removeToken] = useLocalStorage("token", "foo"); // 초기값은 foo 입니다
return (
<div>
<div>Value: {token}</div>
<button onClick={() => setToken("bar")}>bar</button>
<button onClick={() => setToken("baz")}>baz</button>
<button onClick={() => removeToken()}>Remove</button>
</div>
);
}
- react-use 라이브러리의 useHover : 특정 요소가 hover 됐는지 확인할 때 사용
import { useHover } from "react-use";
const App = () => {
// 여기에서 함수의 hovered 인자를 사용할 수 있습니다
const element = (hovered: boolean) => (
<p>Sample text which is {hovered ? "hovered" : "not hovered"}</p>
);
// 혹은 훅으로부터 hovered 상태값을 얻을 수 있습니다
const [textElement, isHovered] = useHover(element);
return <div>{textElement}</div>;
};
- react-use 라이브러리의 useIdle : 사용자가 유휴 상태인지 활성 상태인지 확인하기 위해 사용
import { useIdle } from "react-use";
const App = () => {
const isIdle = useIdle(3000); // 만약 사용자가 3초 이상 유휴상태가 되면 true를 반환합니다
return <div>{isIdle ? "User is idle" : "User is not idle"}</div>;
};
- react-use 라이브러리의 useClickAway : 특정 UI 컴포넌트의 외부를 클릭할 때마다 함수를 트리거할 때 사용
import { useClickAway } from "react-use";
const App = () => {
const ref = useRef(null);
useClickAway(ref, () => {
console.log("OUTSIDE CLICKED");
});
return (
<div
ref={ref}
style={{
width: 200,
height: 200,
background: "red",
}}
/>
);
};
- react-use 라이브러리의 useDebounce : 사용자가 입력을 마칠 때까지 기다린 후 요청 보냄
import { useDebounce } from "react-use";
const App = () => {
const [input, setInput] = useState("");
const [loading, setLoading] = useState(false);
useDebounce(
() => {
setLoading(true);
// 여기에서 api 요청을 합니다
// ...
// ...
setLoading(false);
},
500,
// 함수를 실행하기 전 기다릴 시간(밀리초)입니다
[input] // 변화를 감지할 의존성값입니다
);
return <input value={input} onChange={(e) => setInput(e.target.value)} />;
};
- react-use 라이브러리의 useWindowSize : 스크린의 너비, 높이 값 반환하고 스크린 사이즈가 변할 때 자동으로 그 값 업데이트
import { useWindowSize } from "react-use";
const App = () => {
// window의 높이와 너비값을 가져옵니다
const { width, height } = useWindowSize();
return (
<div>
<div>width: {width}</div>
<div>height: {height}</div>
</div>
);
};
- swr 라이브러리의 useSwr : 컴포넌트가 마운트 될 때 발생하는 요청 쉽게 처리
import useSWR from "swr";
const fetcher = (url: string) => fetch(url).then((r) => r.json());
const App = () => {
const { data, mutate, error, isValidating } = useSWR(
"https://jsonplaceholder.typicode.com/todos/1",
fetcher
);
if (error) return <div>failed to load</div>;
if (!data) return <div>loading...</div>;
return <div>Todo title: {data.title}!</div>;
};
2. 리액트에서 useState를 사용하면서 저지를 수 있는 흔한 실수들
- 불필요한 상태 변수
function RedundantState() {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [fullName, setFullName] = useState("");
const onChangeFirstName = (event) => {
setFirstName(event.target.value);
setFullName(`${event.target.value} ${lastName}`);
};
const onChangeLastName = (event) => {
setLastName(event.target.value);
setFullName(`${firstName} ${event.target.value}`);
};
.
.
.
다음과 같이 수정 가능
export function RedundantState() {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const fullName = `${firstName} ${lastName}`;
...
return (
<>
<form>
...
</form>
<div>Full name: {fullName}</div>
</>
);
}
- 중복 상태
function DuplicateState({ items }) {
const [selectedItem, setSelectedItem] = useState();
const onClickItem = (item) => {
setSelectedItem(item);
};
return (
<>
{selectedItem && <Modal item={selectedItem} />}
<ul>
{items.map((row) => (
<li key={row.id}>
{row.text}
<button onClick={() => onClickItem(row)}>Open</button>
</li>
))}
</ul>
</>
);
}
다음과 같이 수정 가능
아이템 자체를 복사하는 것이 아니라 id 값만 가져옴
아이템이 중복되게 발생하면 만약 사용자가 아이템을 수정했을 때 불필요하게 로직이 복잡해질 수 있다
function DuplicateState({ items }) {
const [selectedItemId, setSelectedItemId] = useState();
const selectedItem = items.find(({ id }) => id === selectedItemId);
const onClickItem = (itemId) => {
setSelectedItemId(itemId);
};
return (
<>
{selectedItem && <Modal item={selectedItem} />}
<ul>
{items.map((row) => (
<li key={row.id}>
{row.text}
<button onClick={() => onClickItem(row.id)}>Open</button>
</li>
))}
</ul>
</>
);
}
- useEffect를 통한 상태 업데이트
function DuplicateState({ items }) {
const [selectedItem, setSelectedItem] = useState();
useEffect(() => {
if (selectedItem) {
setSelectedItem(items.find(({ id }) => id === selectedItem.id));
}
}, [items]);
const onClickItem = (item) => {
setSelectedItem(item);
};
return (
<>
{selectedItem && <Modal item={selectedItem} />}
<ul>
{items.map((row) => (
<li key={row.id}>
{row.text}
<button onClick={() => onClickItem(row)}>Open</button>
</li>
))}
</ul>
</>
);
}
useEffect가 적을 수록 좋다
useEffect 내에서 상태를 업데이트하면 추가 렌더링 발생
function DuplicateState({ items }) {
const [selectedItemId, setSelectedItemId] = useState();
const selectedItem = items.find(({ id }) => id === selectedItemId);
const onClickItem = (id) => {
setSelectedItem(id);
};
return (
<>
{selectedItem && <Modal item={selectedItem} />}
<ul>
{items.map((row) => (
<li key={row.id}>
{row.text}
<button onClick={() => onClickItem(row.id)}>Open</button>
</li>
))}
</ul>
</>
);
}
728x90
'FE > 리뷰' 카테고리의 다른 글
모던 자바스크립트 딥다이브 5장 정리 (0) | 2024.02.29 |
---|---|
모던 자바스크립트 딥다이브 4장 정리 (0) | 2024.02.28 |
모던 자바스크립트 3장 정리 (0) | 2024.02.19 |
모던 자바스크립트 딥다이브 2장 정리 (0) | 2024.02.15 |
[FE / REVIEW] 0205 Article 리뷰 (0) | 2024.02.05 |