[React] 미들웨어와 리덕스 데브툴즈, 리듀서 쪼개기, 더미데이터와 포스트폼 만들기

Yuri Lee·2022년 5월 22일
0

이 글은 인프런 제로초님의 '[리뉴얼] React로 NodeBird SNS 만들기' 를 바탕으로 정리한 내용입니다.

미들웨어와 리덕스 데브툴즈

개발용 미들웨어와 배포용 미들웨어가 다르다.

npm i redux-devtools-extension

→ 이게 있어야 브라우저 크롬 익스텐션과 연동할 수 있음.

const enhancer = process.env.NODE_ENV === 'production'
        ? compose(applyMiddleware([]))
        : composeWithDevTools(applyMiddleware([]))

→ DevTools 을 연결 O (dev)/ 연결 X(prod)
→ enchacer은 리덕스의 기능이 확장된 것을 의미한다.

const configureStore = () => {
    const middlewares = []
    const enhancer = process.env.NODE_ENV === 'production'
        ? compose(applyMiddleware(...middlewares))
        : composeWithDevTools(applyMiddleware(...middlewares))
    const store = createStore(reducer, enhancer);
    return store;
};

→ 리덕스 데브툴즈에서 보통 Diff와 State를 많이 사용한다.
→ 불변성을 지켜서 리턴하기 때문에 히스토리가 유지될 수 있는 것이다.

포트 변경하는 방법

"scripts": {
    "dev": "next -p 3000",
    "build": "next build"
  },

→ 기본은 3000이지만, 바꿀 수 있다.

리듀서 쪼개기

  • 파일들을 적절하게 쪼개기가 필요하다. (ex. user.js , post.js)
  • 리듀서란 이전 스테이트와 액션을 받아셔 다음 스테이트를 돌려주는 함수이다.

combineReducers

리덕스에는 리듀서들을 합쳐주는 combineReducers 메서드가 존재한다.

Q. 왜 쉽게 합치지 못하는 이유는?
→ 리듀서는 함수이다. 함수이기 때문에 함수들을 합치는 것은 쉽지 않다. (객체는 쉬움) 따라서 combineReducers 을 사용한다.

hydration (+ 더 공부하기)

리액트 서버 사이드 렌더링을 위해서 Hydration 을 넣어줘야 한다. 이를 위해서 index reducer를 추가해준다.

const rootReducer = combineReducers({
    index: (state = {}, action) => {
        switch (action.type) {
            case HYDRATE:
                console.log('HYDRATE', action)
                return {
                    ...state, ...action.payload
                }
            default:
                return{
                    state,
                }
        }
    },
    user,
    post,
})

리덕스 개념을 이해하고, 이를 실제로 구현, 컴포넌트에서 useSelector를 이용해서 받아서 쓰고, action을 dispatch 하는 프로세스를 이해하는 게 핵심이다. 👍

구조 분해 할당

const isLoggedIn = useSelector((state) => state.user.isLoggedIn)
const { isLoggedIn } = useSelector((state) => state.user)

→ 구조 분해 할당을 이용해 표현 할 수도 있다. 스타일의 차이!

더미 데이터와 포스트폼 만들기

스타일드 컴포넌트는 서버사이드 렌더링을 설정하지 않았기 때문에 적용이 안되고 있다. 버사이드 렌더링은 프론트엔드 서버에서 html 데이터와 합쳐서 그려준다. 스타일드 컴포넌트는 아직 설정을 안했기 때문에 서버쪽에서 스타일드 컴포넌트가 적용이 안된채로 내려오는 것이다. 다른 페이지를 갔다가 오면 적용된다.

더미 데이터 만들기

export const initialState = {
    mainPosts: [{
      id: 1,
      User: {
        id: 1,
        nickname: '철수',
      },
      content: 'first post!',
      Images: [{
        src: '...',
      }, {
        src: '...',
      }, {
        src: '...',,
      }],
      Comments: [{
        User: {
          nickname: '철수2',
        },
        content: 'hello',
      }, {
        User: {
          nickname: '철수3',
        },
        content: 'world',
      }]
    }],
    imagePaths: [],
    postAdded: false,
};

Q, 어떤 것은 소문자(id, content), 어떤 것은 대문자(User, Images)일까?

DB의 시퀄라이즈 와 관련이 있다. 어떤 정보와 다른 정보와 관계가 있을 경우 합쳐준다. id, content는 게시글 자체의 속성이고, 나머지는 다른 정보들과 합쳐서 주기 때문에 대문자로 설정한 것이다. 프론트엔드 개발자라면 어떻게 데이터를 보내줄 것인지 백엔드 분께 물어봐야 한다.

case ADD_POST:
      return {
          ...state,
          mainPosts: [dummyPost, ...state.mainPosts]
      }

→ dummyPost 앞에다가 추가해야만 게시글 위에 올라간다.

Tips💨

  • 데이터를 먼저 구성하고, 액션을 구성해서 리듀서를 작성하면 된다. 데이터 → 서버 개발자와 리덕스 구조에 대해 합의를 봐야 한다. 합의점에 도달해야 계획 세울 때 좋다.
  • 의미있는 컴포넌트를 먼저 설정한다.
  • 바뀌지 않거나 반복문이 없을 때는 key를 인덱스로 사용해도 좋다. (특히 게시글이 지워질 가능성이 있을 경우 사용해선 안됨)
  • 인라인 스타일 엄청나게 성능에 문제가 되진 않음. 나중에 최적화해도 된다.
  • next 에서 React 를 안써도 되는데 eslint 를 사용하면 에러가 뜬다. 실제로는 아무런 문제가 없다.
  • 글자를 입력했을 때 object, object 가 떴다는 것은 문자열이 객체로 변환되고 있다는 것이다.
const onSubmit = useCallback(() => {
        dispatch(addPost)
    },[])

addPost는 객체이다. 액션은 원래 객체이다. 동적으로 액션이 필요할 때는 액션 크리에이터라는 함수를 만들어주는 것이다. 디스패치 자리에는 객체가 들어가는 것이 맞다.

ref는 언제 사용할까?

→ 실제 돔에 접근해야 할때

profile
Step by step goes a long way ✨

0개의 댓글