ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ReactJS - #1 기초 및 실습 (2주차)
    React 2020. 12. 17. 18:23

    #1 기초 및 실습 (2주차)

     

     

    nextjs.org/docs/basic-features/pages

     

    Basic Features: Pages | Next.js

    Next.js pages are React Components exported in a file in the pages directory. Learn how they work here.

    nextjs.org

     

    next.js는 기본적으로 page routing 방식을 밑에 형식과 같이 지원해준다.

     

     

     


    next.js에서 자체적으로 지원해주는 LinkRouter 기능

    위 코드와 같이 import 를 한 후

     

    요런 식으로 써주게 되면 'pages/class.js' 로 자동으로 routing된다

     

    페이지 이동이 좀 자유로운 장점이 있다.

     

    이런식으로도 쿼리스트링으로도 넘길 수 있다.


    폴더 구조 세팅

    이런식으로 폴더구조를 생성해주고

     

    server.js를 세팅하기 위해 기본적으로 필요한 express, cookie-parser, morgan, express-session을 install한다

     

    jaeho@jaehoiui-MacBookPro my-app % npm install --save express morgan cookie-parser express-session

    * 중간에 --save를 붙여주는 이유는 아마도 package.json 안의 dependencies 부분에 명시적으로 표시해주려고 하는 듯?

     

     

    그런 다음에 server.js에 다음코드를 추가한다.

    const express = require('express');
    const next = require('next');
    const morgan = require('morgan');
    const cookieParser = require('cookie-parser');
    const expressSession = require('express-session');
    

     

    그리고 밑에 서버를 만들어주는 기본 코드를 추가한다.

     

     * 그리고 주석을 꼭 읽어보고 다시 생각해보자

    const express = require('express');
    const next = require('next');
    const morgan = require('morgan');
    const cookieParser = require('cookie-parser');
    const expressSession = require('express-session');
    
    const dev = process.env.NODE_ENV !== 'production';
    
    // app 자체를 next구조대로 가져온다.
    // 기본적인 handler와 app자체는 next.js를 기반 
    const app = next({ dev });
    const handle = app.getRequestHandler();
    
    app.prepare().then( () => {
        // next가 준비가 되면 next안에서 express를 불러온다.
        const server = express();
    
        // server로 express 세팅해주는 부분
        server.use(morgan('dev'));
        server.use(express.json());
        server.use(express.urlencoded({ extended : true}));
        server.use(cookeParser('!ASD!ASd!AVZXC!@#123'));
    
        server.use(
            expressSession({
                resave : false,
                saveUninitialized : false,
                secret : '!ASD!ASd!AVZXC!@#123',
                cookie : {
                    httpOnly : true,
                    secure : false,
                },
            }),
        );
    
        // 라우팅을 하는 과정을 실질적으로는 next에 내장된 자체 핸들러에서 처리를 하고 있다고 생각했을때 제약이 있다.
        // 어떤 규칙을 지켜야하고 우리가 원하는 식의 코드 특히, 웹어플리케이션의 시멘틱한 구조를 자신의 기본적인 라우팅 과정에서 인식하지 못하는 경우가 생긴다.
        // 위처럼 라우팅 자체를 통제하는 방식 , page단위의 queryProps로 관리하는 방법의 예
        // server.get('*')보다 직접 라우팅하는 코드가 위에 있어야 한다.
        // 쿼리스트링으로 next에서 데이터를 가져오는 방식에서 이슈가 있는데 새로고침을 했을때 값을 못가져오는 경우가 발생한다.
        // 그래서 이런 구조로 짜서 props형태로 데이터를 유지하기 위해서 서버를 구성한다.
        // 또한, front에서 파일처리 할 때 node.js에서는 aws s3같이 직접 스토리지에 바로 저장하는 구조로 하지 않을때는 멀터라는 모듈을 써서
        // 로컬에 저장해놓고 저장시켜준 파일을 인식시켜서 보내면서 temp파일로 저장하고 삭제하는 방법을 사용하는데 근데 이걸 완전히 page단위에서 처리할 수 는 없기때문에
        // 항상 ajax라던지 로컬서버로 연결을 시키는 과정이 필요한데 이럴때 server가 필요하다. 
        // 여기서 구성하는 서버는 백엔드가 만든 어떤 데이터를 연결시켜주고 서버환경을 구축하기 위해서 만들어준 서버보다는 front-end 단위에서 rendering에 도움을 준다던지
        // 우리가 프론트 쪽에서 직접 작업하기 어려운 코드들을 로컬서버에서 작동시키기 위해 구축하는 경우가 있다.
        // 이 밑에 코드를 달지 않으면 next는 기본적으로 csr을 기본으로 작동한다.  
        server.get('/product/:id/:name/:name/:price', (res, req) => {
            const actualPage = '/product_detail';
            const queryParams = {
                id : req.params.id,
                name : req.params.name,
                price : req.prarms.price
            }
            // 이렇게 queryParams로 정리해서 page에 보내면 page에서는 props로 받아서 사용할 수 있다.
            return app.render(req, res, actualPage, queryParams);
            
        })
    
    
        // 페이지 props를 연결하는 과정을 이렇게 간단하게 만들어놓은것 -> next에서 ssr을 사용할때 이런 구조를 사용해라라는 document 
        // 이걸안하면 page단위 라우팅이 안된다.
        
        server.get('*', (req, res) =>{
            return handle(req, res);
        })
    
        server.listen(3000, () => {
            console.log('next + express running on port 3000');
        })
    })

     

    추가 설명

     

    웹이라고 하는게 쿼리스트링이나 시멘틱한 것들이 필요한가 생각하면 모바일 어플리케이션에서는

     

    페이지가 스텍으로 쌓이는 개념이라 유지를 시킬 수 있는데 웹은 페이지가 넘어가거나 전환이 되어버리면

     

    세션이나 쿠키나 로컬 스토리지에 저장하고 따로 호출하지 않으면 연결이 되지 않는 구조가 많다.

     

    그렇다고 전부 저장하고 호출할 수 없기 때문에 쿼리스트링이나 시멘틱한 구조의 데이터 전달과정이 필요하다.


    기본적인 서버 구축이 끝났으면 잘 작동이 되는지 점검을 해야하는데

     

    package.json파일에서 start를 "next start" 에서 "node server.js"로 바꿔준다.

     

    실행시키는 코드는 다음과 같다

    jaeho@jaehoiui-MacBookPro my-app % npm run build && npm start

    해당 명령어를 실행했을때 inex.js에서 style에 대한 코드를 수정안한 부분 때문에 빌드가 제대로 되지 않아 

     

    css를 참조하는 코드를 지우고 다시 run

    그럼 아래 화면처럼 잘 처리되는 것을 확인할 수 있다.

    이렇게 된~줄 알았겠지만 사실 다시보면 ReferenceError가 발생한것을 확인할 수 있는데

     

    cookieParser를 cookeParser라고 오타를 쳐서 발생한 에러, 해당 코드를 수정한 뒤 서버를 돌리고 웹페이지로 들어가보면

     

    이러한 화면이 출력되는 것을 확인할 수 있다.

     


    nodemon moduel설치

     

    서버에 변경사항이 있을때마다 자동 재실행해주는 모듈, 편하게 작업하기 위해 설치하는 모듈이다라고 생각하면 편하다.

     

    보통 설치할때 글로벌로 설치하는게 좋다.

     

    -g

    jaeho@jaehoiui-MacBookPro my-app % sudo npm install -g nodemon

     

    그리고 script 의 dev를 다음과 같이 바꿔준다.

     


    styled-components install

    jaeho@jaehoiui-MacBookPro my-app % npm install --save babel-plugin-styled-components styled-components

    .babelrc 파일 생성

     

    그 안에 stlyed-components 기본세팅 코드 작성

    {
        "presets": ["next/babel"],
        "plugins": [
            [
                "styled-components",
                {
                    "ssr" : true,
                    "displayName" : true,
                    "preprocess" : false
                }
            ]
        ]
    }

     

    styled-components를 이용해서 내부 스타일링을 할때만 하면된다.

     

    sass로 세팅하는 경우는 styled-components를 install해서 사용할 필요가 없다.

     


    _document 파일 생성

     

    _document는 next document라고 해서 next자체가 seo를 할수 있다고 말한게 next 안에서 DOM구조, html이 가지고있는 document

     

    구조를 기능화해서 만들어 놓았기 때문이라고 생각하면 된다.

    import Document, { Head, Main, NextScript } from 'next/document';
    
    export default class MyDocument extends Document{
        render(){
            return (
                <html lang = "en">
                    <Head>
                            <meta charSet="utf-8" />
                            <title>React Practice</title>
                            <meta name="viewport" content="width=device-width, initial-scale-1.0, maximum-scale=1, user-scalable=no" />
                            {/* 스타일 시트 링크 */}
                            {/* 웹폰트 임포팅 */}
                            {/* 메타설정 */}
                    </Head>
                    <body>
                        <Main /> {/* 라우터에 해당하는 페이지가 렌더링 되는 부분 */ }
                        <NextScript /> {/* Next 관련 된 자바스크립트 파일 */}
                    </body>
                </html>
            )
        }
    }
    
    // import { ServerStyleSheet } from 'styled-components';
    
    // export default class MyDocument extends Document{
    //     static getInitialProps({ renderPage }){
    //         // step 1 : Create an instance of ServerStyleSheet
    
    //         const sheet = ServerStyleSheet();
    
    //         // step2 : Retrieve styles from components in the page
    //         const page = renderPage(App => props => sheet.collectStyles(<App {...props} />));
    
    //         // Step 3 : Extract the styles as <style> tags
    //         const styleTags = sheet.getStyleElement();
    
    //         // step 4: Pass styleTags as a prop
    //         return { ...page, styleTags};
    //     }
    //     render(){
    //         return (
    //             <html>
    //                 <Head>
    //                     {/* step 5 : Output the styles in the head` */}
    //                     <meta charSet='utf-8'/>
    //                     <meta name='viewport' content='initial-scale=1.0, width=device-width' />
    //                     {this.props.styleTags}
    //                 </Head>
    //                 <body>
    //                     <Main />
    //                     <NextScript />
    //                 </body>
    //             </html>
    //         );
    //     }
    // }

     

    이렇게 한후에 서버를 실행시키면

     

    우리가 설정했던 설정들이 페이지에 들어가 있는 것을 확인할 수 있다.


     

    'React' 카테고리의 다른 글

    ReactJS - #3 기초 및 실습 (2주차)  (0) 2020.12.20
    ReactJS - #5 기초 및 실습 (1주차)  (0) 2020.12.17
    ReactJS - #4 기초 및 실습  (0) 2020.12.16
    ReactJS - #3 기초 및 실습  (0) 2020.12.16
    ReactJS - #2 기초 및 실습  (0) 2020.12.16

    댓글

Designed by Tistory.