리액트 - 사용자 경험 개선 - 포스트 리스트 데이터 유지 및 포스트 데이터 초기화

정영찬·2022년 4월 25일
0

리액트

목록 보기
67/79
post-custom-banner

불필요한 재로딩 현상 없애기

포스트 리스트를 구현한 것 까지는 좋았지만, 사용자의 입장에서는 불편할 수 있는 점이 보인다.
예를 들면 항목하나를 클릭해서 로딩을 통해 데이터를 보여주고 난뒤, 뒤로 가면 로딩시간을 또 기다려야 한다.

굳이 이렇게 다시 로딩을 해서 기다려야 할까? 더 좋게 만들 수는 없을까?
재로딩 해결은 간단하다. PostListContainer에서 useEffect의 내용을 수정해주면 된다.

데이터가 있다면? dispatch하지 마라.

    useEffect(() => {
      if(data) return;
        dispatch(getPosts())
    },[dispatch, data])

이렇게 data 값이 있다면 그냥 return 하게 하면 된다.


이제 뒤로가기를 눌러도 로딩중이라는 문구가 나타나지 않는다.

여기서 더 개선해서 로딩중이라는 문구는 나타나지 않고 ,데이터를 업데이트하는 기능을 추가해보다.

asyncUtils.js 에서 handleAsyncActions 에서 새로운 파라미터를 추가한다.
keepData : true 일 경우 state[key].data로 업데이트를 하고, false 일 경우는 null로 변경한다.

export const handleAsyncActions = (type, key, keepData) => {
  const [SUCCESS, ERROR] = [`${type}_SUCCESS`, `${type}_ERROR`];
  return (state, action) => {
    switch (action.type) {
      case type:
        return {
          ...state,
          [key]: reducerUtils.loading(keepData ? state[key].data : null),
        };

PostListContainer.js 에서 useEffect에 작성한 내용 대신에 loading && !data일 경우 로딩중 화면을 렌더링하게 수정해준다.

    useEffect(() => {
        dispatch(getPosts())
    },[dispatch])

    if (loading && !data) return <div>로딩중...</div>
    if (error) return <div>에러 발생!</div>
    if (!data) return null

마지막으로 유틸함수에서 keepData 파라미터를 추가했으니, posts.js 모듈에서도 파라미터를 추가해야한다.

const getPostsReducer = handleAsyncActions(GET_POSTS, 'posts', true)

이제 다시 돌려보면

뒤로가기로 메인화면으로 돌아갈때 로딩중... 이라는 화면은 나타나지 않지만, GET_POSTS와 GET_POSTS_SUCCESS가 dispatch되는 모습을 볼수 있다.

post 데이터 초기화

두번째 문제는 항목을 클릭하고 뒤로와서 다른 항목을 클릭하면 짧은 시간 동안 이전의 항목 데이터가 보여지는 현상이 생긴다.

gif 로는 잘 안보이지만, 육안으로 봤을때는 현상이 잘 보인다.

해결방법 상태를 초기화하는 액션타입을 하나 추가한다.

posts.js 모듈에서 CLEAR_POST 라는 액션 타입을 추가한다.

const CLEAR_POST = 'CLEAR_POST'

그리고 thunk 생성함수도 하나 추가한다.

export const clearPost = () => ({type: CLEAR_POST})

리듀서에도 case를 하나 추가해서 데이터값을 initial값으로 초기화 하는 동작을 추가한다.

case CLEAR_POST:
      return {
        ...state,
        post: reducerUtils.initial()
      }

PostContainer.js 에서 useEffect의 내용을 수정한다. 뒤로가기를 누르면 clearPost가 dispatch 되게끔 return 값을 지정한다. 따라서 postId 값이 바뀌거나 컴포넌트가 unmount 되면 getPost를 dispatch 하기 직전에 clearPost가 먼저 dispatch된다.

useEffect(()=> {
        dispatch(getPost(postId))
        return () => {
          dispatch(clearPost())
        }
    },[postId, dispatch]);

clearPost가 먼저 dispatch되어 post의 data를 null값으로 변경되어서 이전의 데이터 내용이 전혀 보이지 않게 되었다.

profile
개발자 꿈나무
post-custom-banner

0개의 댓글