[React] redux 리팩토링 & custom hook

Hyowmls·2024년 6월 5일
0
post-thumbnail

2024.06.05

팀프로젝트를 하면서 게시물 생성 파트를 만들기로 했다
코드를 작성하고 나서 redux로 리팩토링을 하기로 했다

slice

redux/slices 폴더에 postSlice.jsx를 하나 만들어 그 안에 코드를 작성했다
createSlice를 임포트 할 때 계속 경로가 이상해져서 오류가 발생해서 @reduxjs/toolkit 를 직접 입력했다

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  name :'',
  title : '',
  content :'',
  tag : [],
  previews : [],
  userEmail : '',
  titleError : '',
  contentError : '',
  userId : '',
}

const postSlice = createSlice({
  name : 'post',
  initialState,
  reducers : {
    setName : (state, action) => {
      state.name = action.payload
    },
    setTitle : (state, action) => {
      state.title = action.payload
    },
    setContent : (state, action) => {
      state.content = action.payload
    },
    setTag : (state, action) => {
      state.tag = action.payload
    },
    setPreviews : (state, action) => {
      state.previews = action.payload
    },
    setUserEmail : (state, action) => {
      state.userEmail = action.payload
    },
    setTitleError : (state, action) => {
      state.titleError = action.payload
    },
    setContentError : (state, action) => {
      state.contentError = action.payload
    },
    setUserId : (state, action) => {
      state.userId = action.payload
    }
  }
})
export const {
  setName,
  setTitle,
  setContent,
  setTag,
  setImages,
  setPreviews,
  setUserEmail,
  setTitleError,
  setContentError,
  setUserId
} = postSlice.actions

export default postSlice.reducer

configStore

import { configureStore } from '@reduxjs/toolkit';
import authReducer from '../slices/authSlice';
import postReducer from '../slices/postSlice'
const store = configureStore({
  reducer: {
    auth: authReducer,
    post: postReducer,
  },
});

export default store;

팀원분이 먼저 auth를 작성해주셔서 그냥 그 아래에 따라서 작성했다

그리고 main.jsx에도 Provider로 감싸줘야 하는데 팀원분이 미리 작성해두셔서 스킵

Custom Hook

리팩토링을 했는데 게시물 생성 페이지의 코드가 아직도 복잡해서 custom hook을 만들어서 가독성을 향상 시키려 했다

export const useCreatePost = () => {
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const { title, content, tag, previews, userEmail, titleError, contentError,userId } = useSelector((state) => state.post);
  const [images, setImages] = useState([])
  const [disabled, setDisabled] = useState(false)
  
  useEffect(() => {
    const fetchUserData = async () => {
      const { data: { user } } = await supabase.auth.getUser();
      if (user) {
        dispatch(setUserEmail(user.email));
        dispatch(setUserId(user.id))
      }
    };
    fetchUserData();
  }, [dispatch]);
  
  // 게시물 생성 페이지에 있는 로직들 ~
  
  return {
	title, content, tag, previews, useEmail
    // 기타 함수 및 변수들 ~
  }
}

useDispatch로 액션을 redux 스토어에 전달하고 useSeletor로 redux 스토어에 있는 상태들를 선택하여 가져왔다.

page 결과

import { useCreatePost } from '../components/createpost/useCreatePost';

  const {
    handleSubmit,
    handleImageChange,
    showHashTag,
    hashTagRef,
    navigate,
    disabled,
  } = useCreatePost();
  

useCreatePost() - 커스텀 훅에서 필요한 것들만 가져왔다

  return (
    <div>
      <Form handleSubmit={handleSubmit}>
        <Top navigate={navigate} disabled={disabled}/>
        <Input />
        <ImageUpload handleImageChange={handleImageChange} />
        <HashTag hashTagRef={hashTagRef} showHashTag={showHashTag} />
      </Form>
    </div>
  );

리팩토링을 하기전에는 자식에게 props를 너무 많이 내려줘서 코드를 읽을때 너무 힘들었는데
전역상태 관리로 자식 컴포넌트에서 필요한 부분은 useSeletor를 사용해서 가져오면 되니까 코드 가독성이 좋아졌다

0개의 댓글