서버사이드 렌더링 CSR(Client Side Rendering) 서버에서 HTML을 처리하지 않고, 브라우저의 자바스크립트를 통해 상호작용하여 전달해주는 방식. 장점 사이트 상호작용에 있어 활발 초기 로딩 후 빠른 웹사이트 렌더링 웹애플리케이션에 좋음 자바스크립트 라이브러리 활용 단점 제대로 구현하지 않을 시 SEO(검색최적화)가 취약 초기 로딩에 많은 시간이 걸림 대부분 추가적인 라이브러리가 필요 SSR(Server Side Rendering) 서버에 HTML 파일을 저장해두었다가 요청이 발생할 때 모든 파일을 브라우저에 전달하는 방식. SEO, 크롤링에 최적화 되어 있습니다. 장점 검색엔진 SEO에 최적화 초기 화면 로딩이 빠름 단점 잦은 서버 요청 전체적으로 느린 페이지 렌더링 모든 페이지를 리로..
쿼리스트링과 lastId 방식 현재 스크롤을 내리면 같은 게시글을 계속 불러오는 버그가 있습니다. 여러 방법 중 lastId 방식으로 이 문제를 해결하는데, 먼저 mainPosts의 마지막(첫번째) 게시글의 id를 찾아서 이걸 lastId로 데이터를 전달해줍니다. 하지만, get방식은 데이터를 보낼 수 없기 때문에 넣으려면 쿼리스트링(`/주소?key=${value}`)를 이용해야 됩니다. 쿼리스트링의 값은 req.query에 담겨있으므로 req.query.lastId를 백엔드에서 값으로 사용합니다. 또한, 서비스가 처음 시작되는 경우, lastId의 값이 undefined가 되어버려서 에러가 발생할 수 있습니다. 초기로딩이 아닐시에는 if(parseInt(req.query.lastId, 10)) 구문을 ..
이미지 업로드를 위한 multer encType="multipart/form-data" 이미지를 올리게되면 multipart 라는 form-data로 데이터가 전송이 되게 됩니다. 하지만, 지금의 백엔드에서는 json 형식과 이미지나 비디오 같은 데이터를 받을 수 없는 일반적인 Form 데이터만 받을 수 있기 때문에 multer를 설치합니다. multer는 app.js에서 미들웨어로 전체 라우터에 연결해줄 수 있지만 어떤 게시글은 text, 이미지만 올릴 수 있기때문에 라우터에 적용합니다. storage: 파일이 저장될 위치를 설정함 diskStorage: 파일을 디스크에 저장함 destination: 파일이 어떤 디렉토리(폴더)에 저장될 것인지 설정하는 메서드 filename: 폴더 내 저장될 파일의 ..
리액트의 불변성을 지키려고 하면 위 그림처럼 길게 써야되고, 초보자가 하기에는 무리가 있습니다. 코드가 오류나기도 쉽기 때문입니다. 따라서, 이런 문제를 해결하기 위해 immer라는 라이브러리를 사용합니다. return produce(state, (draft) => { });가 기본 모양이고, 이를 이용하여 코드를 작성하면 됩니다. draft.뒤에 코드를 작성해주면 되고, immer를 사용하게 되면 코드량이 감소되고, 가독성, 생산성이 높아져 보다 깔끔한 코드를 작성할 수 있습니다.
리덕스 사가는 리액트의 사이드 이펙트만 담당하는 미들웨어 중 하나로, 우리의 앱에서 액션을 받아 처리하고, 멈추고, 취소할 수 있게 만들어주고, 리덕스 상태에 접근하여 액션을 디스패치할 수 있습니다. 또한, 비동기 흐름을 쉽게 읽고, 쓰고, 테스트할 수 있는 ES6 문법인 제너레이터를 사용할 수 있습니다. npm을 이용하여 리덕스사가와 넥스트와 리덕스사가를 연결하는 next-redux-saga도 설치해줍니다. createSagaMiddleware로 선언을 해준뒤 const middleware = [sagaMiddleware];로 연결만 해주면 됩니다. rootSaga를 이용하기 때문에 sagas/index.js 만들어줍니다. 사가는 function* () 제너레이터를 이용합니다. 제너레이터는 아래 그림처..
PostCard 역시 큼직큼직하게 컴포넌트를 생각하고 기획하고, 기획을 하면 됩니다. 그리고 살을 붙이듯 구현을 해나가면 됩니다. post를 props로 데이터를 index.js에서 받아오기때문에 propTypes를 설정해주어야합니다. proptypes설정시 object 항목을 더 자세하게 적어주고 싶다면, shape({ }) 안에 넣어주면 됩니다. 또한, 옵셔널체이닝 연산자로 const id = me && me.id; 에서 const id = me?.id;로 변경할 수 있으며, 이또한 const id = useSelector((state) => state.user.me?.id) 처럼 사용할 수도 있습니다. state 값이 false일 때, 값을 true로 변경하거나 true값을 false로 변경하려면 ..
Reducer들도 컴포넌트들처럼 쪼갤 수 있습니다. reducers 디렉토리 안에 분리시킬 post, user.js를 만들어주고, index.js에서 있던 initialState와 action들을 각 파일에 옮겨줍니다. 리듀서들도 옮겨서 적어주고, index.js에 분리시킨 리듀서들을 import 시켜줍니다. 리덕스에서는 분리시킨 리듀서들을 가져오려면 combineReducers을 사용하여 묶을 수 있고, const rootReducer = combineReducers({ user, post, }); 로 할 수 있지만, 추후 SSR(Server Side Rendering) 때문에 HYDRATE를 위해 index 항목을 추가해줍니다. 리듀서들을 combineReducers로 묶어주는 이유는 리듀서들은 함수..