인프런 커뮤니티 질문&답변

정중한 전어님의 프로필 이미지
정중한 전어

작성한 질문수

React로 NodeBird SNS 만들기

7-18. 폴더 구조와 _error.js

함수형 컴포넌트의 클래스화

해결된 질문

작성

·

334

0

안녕하세요! 강의 듣고 응용하여 토이프로젝트 진행중인 학생입니다.

해당 강의에서 (7-18. 폴더 구조와 _error.js) next/app의 App을 가져와 class를 감싸주지 않고 그냥 함수형 컴포넌트 방식으로 진행해도 문제는 없지만 혹시 문제가 발생한다면 클래스로 변환해봐라 하셨었는데

_document.js 적용 후에 가끔 이유없이 새로고침 되는 문제가 발생합니다. 경고문에 Container를 더이상 사용하지 말라는 말도 있고, (이렇게 되면 next/app에서 가져온 무언가로 감싸지 않고 진행하는데 이래도 괜찮은건지 모르겠습니다 ㅠㅠ) 제로초님께서 강의 중 하신 말씀도 있고 해서 혹시 하는 마음에 _app.js를 클래스 형태로 변환해보고자 합니다.

변환을 하고 보니 일단은 문제없이 동작하긴 하지만

클래스형 컴포넌트가 익숙하지 않아 제대로 바꾼 것인지 고민이 되어 질문 드립니다!

변환 전, 변환 후 코드를 덧글로 달겠습니다!

한번 확인해주시면 감사하겠습니다 ㅠㅠ

답변 6

1

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

네네 맞습니다.

1

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

잘 바꾸셨습니다. propTypes도 class 안으로 넣으시면 됩니다.

0

감사합니다! 

0

답변 감사합니다! propTypes도 앞에 static 을 붙여 이런식으로 작성하면 되는걸까요?

class DreamWitch extends App{
static propTypes = {
Component: propTypes.elementType.isRequired,
store: propTypes.object.isRequired,
pageProps: propTypes.object.isRequired,
};
static async getInitialProps (context){
const {ctx, Component} = context;
let pageProps = {};
const state= ctx.store.getState();
const cookie = ctx.isServer ? ctx.req.headers.cookie : '';
if(ctx.isServer){
Axios.defaults.headers.cookie = '';
}
if(ctx.isServer && cookie){
Axios.defaults.headers.cookie = cookie;
}
if(!state.user.me){
ctx.store.dispatch({
type:LOAD_USER_REQUEST
})
}
if(Component.getInitialProps){
pageProps = await Component.getInitialProps(ctx) || {};
}
return {pageProps};
}
render(){
const {Component, store, pageProps} = this.props;
return(
렌더내용
)
}
}

0

클래스로 변환한 코드입니다 

import React from "react";
import propTypes from "prop-types";
import withRedux from "next-redux-wrapper";
import withReduxSaga from 'next-redux-saga';
import { createStore, compose, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import reducer from "../reducers";
import createSagaMiddleware from "redux-saga";
import rootsaga from "../sagas";
import {ThemeProvider} from 'styled-components';
import themes from '../components/styledComponents/theme';
import GlobalStyle from '../components/styledComponents/GlobalStyle';
import Axios from "axios";
import { LOAD_USER_REQUEST } from "../reducers/user";
import App from 'next/app';
import {Helmet} from 'react-helmet';

class DreamWitch extends App{
static async getInitialProps (context){
const {ctx, Component} = context;
let pageProps = {};
const state= ctx.store.getState();
const cookie = ctx.isServer ? ctx.req.headers.cookie : '';
if(ctx.isServer){
Axios.defaults.headers.cookie = '';
}
if(ctx.isServer && cookie){
Axios.defaults.headers.cookie = cookie;
}
if(!state.user.me){
ctx.store.dispatch({
type:LOAD_USER_REQUEST
})
}
if(Component.getInitialProps){
pageProps = await Component.getInitialProps(ctx) || {};
}
return {pageProps};
}
render(){
const {Component, store, pageProps} = this.props;
return(
<Provider store={store}>
<Helmet
title="DREAMWITCH :: 꿈의 마녀"
htmlAttributes={{lang:'ko'}}
meta={[{
charset: 'UTF-8'
}, {
name: 'viewport', content: "width=device-width, initial-scale=1",
}, {
'http-equiv': 'X-UA-Compatible', content: 'IE=edge',
}, {
name: 'og:title', content: 'DREAMWITCH :: 꿈의 마녀',
}, {
name: 'og:description', content: '꿈을 이루기 위한 할일 관리 프로젝트',
}, {
property: 'og:type', content: 'website',
}, {
property: 'og:image', content: '/thumb.jpg'
},]}
link={[{
rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css'
}]}
/>
<ThemeProvider theme={themes}>
<GlobalStyle/>
<Component {...pageProps}/>
</ThemeProvider>
</Provider>
)
}
}

DreamWitch.propTypes = {
Component: propTypes.elementType.isRequired,
store: propTypes.object.isRequired,
pageProps: propTypes.object.isRequired,
};

const middleware = (store) => (next) => (action) => {
console.log(action);
next(action);
};

const configureStore = (initialState, options) => {
const sagaMiddleware = createSagaMiddleware();
const middlewares = [
sagaMiddleware,
(store)=>(next)=>(action)=>{
next(action);
}
];
const enhancer =
process.env.NODE_ENV === "production"
? comspose(applyMiddleware(...middlewares))
: compose(
applyMiddleware(...middlewares),
!options.isServer &&
window.__REDUX_DEVTOOLS_EXTENSION__ !== "undefined"
? window.__REDUX_DEVTOOLS_EXTENSION__()
: (f) => f
);
const store = createStore(reducer, initialState, enhancer);
store.sagaTask = sagaMiddleware.run(rootsaga);
return store;
};

export default withRedux(configureStore)(withReduxSaga(DreamWitch));

0

바꾸기 전 코드입니다 

import React from "react";
import propTypes from "prop-types";
import withRedux from "next-redux-wrapper";
import withReduxSaga from 'next-redux-saga';
import { createStore, compose, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import reducer from "../reducers";
import createSagaMiddleware from "redux-saga";
import rootsaga from "../sagas";
import {ThemeProvider} from 'styled-components';
import themes from '../components/styledComponents/theme';
import GlobalStyle from '../components/styledComponents/GlobalStyle';
import Axios from "axios";
import { LOAD_USER_REQUEST } from "../reducers/user";
import {Helmet} from 'react-helmet';

const DreamWitch = ({ Component, store, pageProps }) => (
<>
<Provider store={store}>
<Helmet
title="DREAMWITCH :: 꿈의 마녀"
htmlAttributes={{lang:'ko'}}
meta={[{
charset: 'UTF-8'
}, {
name: 'viewport', content: "width=device-width, initial-scale=1",
}, {
'http-equiv': 'X-UA-Compatible', content: 'IE=edge',
}, {
name: 'og:title', content: 'DREAMWITCH :: 꿈의 마녀',
}, {
name: 'og:description', content: '꿈을 이루기 위한 할일 관리 프로젝트',
}, {
property: 'og:type', content: 'website',
}, {
property: 'og:image', content: '/thumb.jpg'
},]}
link={[{
rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css'
}]}
/>
<ThemeProvider theme={themes}>
<GlobalStyle/>
<Component {...pageProps}/>
</ThemeProvider>
</Provider>
</>
);

DreamWitch.propTypes = {
Component: propTypes.elementType.isRequired,
store: propTypes.object.isRequired,
pageProps: propTypes.object.isRequired,
};

const middleware = (store) => (next) => (action) => {
console.log(action);
next(action);
};

DreamWitch.getInitialProps = async (context) => {
const {ctx, Component} = context;
let pageProps = {};
const state= ctx.store.getState();
const cookie = ctx.isServer ? ctx.req.headers.cookie : '';
if(ctx.isServer){
Axios.defaults.headers.cookie = '';
}
if(ctx.isServer && cookie){
Axios.defaults.headers.cookie = cookie;
}
if(!state.user.me){
ctx.store.dispatch({
type:LOAD_USER_REQUEST
})
}
if(Component.getInitialProps){
pageProps = await Component.getInitialProps(ctx) || {};
}
return {pageProps};
}

const configureStore = (initialState, options) => {
const sagaMiddleware = createSagaMiddleware();
const middlewares = [
sagaMiddleware,
(store)=>(next)=>(action)=>{
next(action);
}
];
const enhancer =
process.env.NODE_ENV === "production"
? comspose(applyMiddleware(...middlewares))
: compose(
applyMiddleware(...middlewares),
!options.isServer &&
window.__REDUX_DEVTOOLS_EXTENSION__ !== "undefined"
? window.__REDUX_DEVTOOLS_EXTENSION__()
: (f) => f
);
const store = createStore(reducer, initialState, enhancer);
store.sagaTask = sagaMiddleware.run(rootsaga);
return store;
};

export default withRedux(configureStore)(withReduxSaga(DreamWitch));
정중한 전어님의 프로필 이미지
정중한 전어

작성한 질문수

질문하기