[react query] 즉시 새로운 데이터를 가져오기
방법 1 queryClient.invalidateQueries({ queryKey }); await queryClient.refetchQueries({ queryKey }); // 데이터를 즉시 새로 가져옴 두 개의 함수를 호출해야 한다는 것, await 에도 주의하자. 방법 2 refetch(); // 데이터를 새로 가져오고 useQuery의 결과를 업데이트
방법 1 queryClient.invalidateQueries({ queryKey }); await queryClient.refetchQueries({ queryKey }); // 데이터를 즉시 새로 가져옴 두 개의 함수를 호출해야 한다는 것, await 에도 주의하자. 방법 2 refetch(); // 데이터를 새로 가져오고 useQuery의 결과를 업데이트
기존에 preview.ts를 사용하고 있었다면, preview.tsx 로 rename. preview.tsx import type { Preview } from "@storybook/react"; import React from "react"; import { FormProvider, useForm } from "react-hook-form"; import "../src/index.css"; /** * 각 컴포넌트에 react-hook-form 이 결합되어 있어서 * storybook 화면에서 에러를 방지하기 위해 global FormProvider wrapping을 수행. */ const formDecorator = (Story) => { const methods… Read More »
Context 라는 이름에서 유추할 수 있듯이, form이 다른 컴포넌트를 포함하고 있다면 해당 컴포넌트의 input까지 register를 내려서 묶을 수 있다.
import 구문을 dist 포함으로 변경해 주어야 한다. Replace import ‘moment/locale/ru’; with import ‘moment/dist/locale/ru’;
커서 위치를 유지하는 것이 포인트 … onChange={(e) => { modifyUpperCase(e, forceUpperCase); }} … export const modifyUpperCase = (e: React.ChangeEvent<any>, forceUpperCase: boolean) => { if (forceUpperCase) { const et = e.target; const selectionStart = et.selectionStart; const selectionEnd = et.selectionEnd; et.value = et.value.toUpperCase(); // 조건에 따라 영대문자 변경 et.setSelectionRange(selectionStart, selectionEnd); // 커서 위치 유지를 위한 작업 }
react component가 공통적으로 갖고 있는 key 속성을 활용한다. number state를 하나 만들어서 key 속성에 바인딩 state 가 change (예: +1) 될 때마다 re-render
환경 "react-hook-form": "^7.34.0" 개요 form.watch 사용시, 모든 form 컴포넌트를 리렌더링하기 때문에, 성능에 영향을 미치는 경우가 있었음. useWatch는 re-rendering의 범위를 단위 컴포넌트 내로 제한하며, 필드명으로 범위를 또 제한할 수가 있었음. 샘플 코드 // fromDate, toDate 두 개의 props를 받는 datepicker에서의 작업예시 const watchVals = useWatch({ control: form.control, name: [fieldName, fieldName2 || 'dummy'] }); 위 샘플에서는 control,… Read More »
React 18의 strict mode 때문이었음
왤까? 왜 그러는 것일까?
배열의 요소를 변경한 후, 배열의 사본을 set 해야 한다. array1 이라는 state라면 => […array1] 로 적용
이동 전 페이지 const navigate = useNavigate(); const goErrorPage = (errMsg: ReactNode) => { navigate('/error', { state: { errMsg } }); }; // 이후 goErrorPage('블라블라') 호출 이동 후 페이지 const { state } = useLocation(); … return <> <h2>{state.errMsg}</h2> </>
원문 출처 https://betterprogramming.pub/loading-third-party-scripts-dynamically-in-reactjs-458c41a7013d script loader as a module const loadGMaps = (callback) => { const existingScript = document.getElementById('googleMaps'); if (!existingScript) { const script = document.createElement('script'); script.src = 'https://maps.googleapis.com/maps/api/js'; script.id = 'googleMaps'; document.body.appendChild(script); script.onload = () => { if (callback) callback(); }; } if (existingScript && callback) callback(); }; export default loadGMaps; 적용 import React, {… Read More »
환경 react 18 @mui/material: 5.11.2 @mui/base의 Modal 컴포넌트를 사용하여 모달 구현 개요 mui의 데모 페이지에서는 모달이 뜬다고 해서 이런 현상이 발생하지 않았다. 우리 사이트의 레이아웃 특성상 발생하는 문제인 것 같다. 헤더(GNB) 영역이 좌우로 왔다갔다 하는 것이 눈에 거슬림 해결 /** * jumping scrollbar issue 해결방안 * * 1) 모달이 뜨면 스크롤바가 사라지면서 header부가 우측으로 밀리고,… Read More »
useMemo를 사용하는 것을 왜 생각 못하고 엉뚱한 곳을 헤멨을까? const randomId = useMemo(() => nanoid(6), []);
개요 보통은 react-use의 useWindowScroll 로 충분하다. 그러나 이번에 작업하는 컴포넌트는 소형 컴포넌트로, 한 페이지 내에 다수가 들어갈 수 있어서 성능을 위해 scroll event에 throttle 처리를 해 주고 싶었음 소스 export const useWinScroll = ({ throttleInterval = 50 }) => { const [scrollX, setScrollX] = useState(window.scrollX); const [scrollY, setScrollY] = useState(window.scrollY); // dc(`## scrollY: [${scrollY}]`); useEffect(()… Read More »
환경 react 18 vite 4 원인 1 스크립트 에러가 존재할 경우 원인 2 정말 알 수 없는 케이스 (URL()이 문제인가? import.meta.url이 문제인가?) export function getImageUrl(filePath: string) { // const ret = import.meta.url; // 문제 없음 // const ret = new URL(`${filePath}`, ''); // 문제 없음 // const ret = new URL('blablabla', import.meta.url).href; // 문제 없음… Read More »
환경 react router 6 개요 vanilla js에서는 window.history.pushState 를 사용한다고 하는데 react router 6 에서는 useNavigate 를 사용하면 된다. const navigate = useNavigate(); const { pathname } = useLocation(); … const handleSearch = () => { const newSearch = new URLSearchParams({ page: 1 } as any).toString(); navigate({ pathname, search: newSearch }); };
이렇게 하는 것이 정석인지 아닌지는 모르겠다. 일단 요건은 만족하는 것으로 보인다. type Props = { … readOnly?: boolean; // true일 경우, 클릭해도 아무 일도 일어나지 않는다. … }; /** * FC */ const Checkbox = ({ … readOnly = false, … }: Props) => { return <input … onClick={(e) => { if (readOnly) e.preventDefault(); }}… Read More »
sendbird UIKit 에서 onBeforeSendFile (맞나?) 를 사용하려다가 sync – async 문제로 안되서 어려워 하다가, fileUploadIconRenderer (맞나?) 를 통해 fileUploadIcon을 아예 새로 만들어서 해결했다고 함.