React study

hong·2026년 1월 12일

조사

목록 보기
14/14

유지보수 하게된 프로젝트가 리액트를 써서 급히 이해한대로 정리 ^^;;

*프로젝트 뼈대!!

  • React 18 + CRA(react-scripts 5) 기반
  • 라우팅: react-router-dom v6
  • UI: MUI(@mui/material) + emotion (styled-components도 같이 있음 → 스타일 방식 혼재 가능성 큼)
  • 상태관리: Redux Toolkit + react-redux + redux-persist + thunk

1. useEffect

``` useEffect(() => { //... }, []); ``` 처음 한번 들어올 때 실행하는게 대부분. 페이지 들어오자마자 api한번 요청의 느낌. 여기서 요청하고 받은 응답으로 이것저것을 한다
    useEffect(() => {
        if (isCheck || modalClose) {
            getAlarm();
            setTimeout(onCancel, 3000);
        }
    }, [isCheck, modalClose]);

이런식으로 쓰였을 땐 deps 바뀌면 effect 재실행

  1. useCallback
const getAlarm = useCallback(() => { ... }, []);

리렌더돼도 같은 함수 객체를 유지해주는 훅. (리랜더 돼도 참조 안바뀜)
-> "이 함수 참조를 고정해서 props/deps 비교에서 불필요한 변경을 막는다."

  1. redux에서의 slice란 ...

전체 전역 state 중에서 한 영역을 잘라낸 조각(slice)

Redux Store (전체 전역 상태)
 ├ user
 ├ auth  -- 이게 하나의 slice
 ├ somethingA
 └ somethingB
  1. redux에서의 initialState, reducers, extraReducers
createSlice({
  initialState, -- store에 넣고 싶은 상태 모양/기본값
  reducers, -- 동기 작업으로 state 바꾸는 규칙
  extraReducers -- 비동기 작업용 thunk가 뿌리는 pending/fulfilled/rejected에 반응해서 state 바꾸는 규칙
});
  1. reducers
  • 동기 작업일 때 state를 변경하고 싶으면 사용한다. 클릭 토글 , UI 상태 변경등.
reducers: {
  setModal(state, action) {
    state.isModal = action.payload;
  }
}

밖에서는 아래와 같이 쓴다.

dispatch(modalActions.setModal(true))
  1. extraActions
    createAsyncThunk 모아둔 비동기 action들
    (API 호출, 파일 읽기/저장, localStorage/IndexedDB 접근,setTimeout 같은 지연 작업 등)
  • createSlice, createAsyncThunk, configureStore는 Redux Toolkit임
  1. extraReducers
  • 주로 createAsyncThunk가 자동으로 만드는 액션들 처리함.
  • 실행하면 나오는 pending(시작) / fulfilled(성공) / rejected(실패)에 반응해서 state 변경하는 규칙
  1. redux-persist
    새로고침해도 남겨둘 전역 state를 localStorage에 자동으로 저장·복원해주는 애

  2. useMemo

const memoValue = useMemo(() => {
  // 계산/생성
  return something;
}, [deps]);

deps 중 하나라도 변경 → 다시 실행 → 새 값 반환
deps 안 변함 → 이전 값 그대로 재사용

  • 혼란 포인트
    const value = useMemo(() => ({a,b,c}), [a,b,c])
    이런 코드가 있었는데요... 저는 이걸 쓰나마나한 코드라고 생각했습니다.
    a가 변하거나 b가 변하거나 c가 변하면 객체 참조를 새로 하는데 이걸 왜 썼을까?
    그런데 리액트는 부모가 리렌더되면 자식도 기본적으로 함수 재실행이 될 수 있는데, 이때 value 객체를 매번 새로 만들면 Context/props의 참조가 바뀐 걸로 인식되어 불필요한 리렌더가 늘어납니다. 그래서 useMemo로 value 객체의 참조를 유지해 불필요한 리렌더를 줄이려는 코드였습니다..
  1. createContext
    컴포넌트 트리 깊숙한 곳까지 props 안 흘리고, 한 번에 값 공유하는 방법.
    Provider로 감쌀 때 의미있어진다.
  • Context value에 값이 바뀌면 Provider 아래 전부 리렌더 될 수 있으니 value를 useMemo로 감싸거나, Context를 쪼개는 게 성능에 좋음
export const SampleContext = createContext(initSampleContext);

...
const value = useMemo(() => ({a,b,c}), [a,b,c])
<SampleContext.Provider value={value}>
...
  1. useLocation
  • react-router-dom 훅
  • 현재 라우트 정보를 줌
profile
프론트엔드 개발을 하고 있습니다 ⌨️

0개의 댓글