ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React.js] 리액트를 이용해서 회원가입 페이지 만들기
    웹/Node.js & React.js 2022. 2. 13. 15:10

    - React는 module과 비슷한 component로 이루어지고 재사용이 뛰어남

    - Virtual DOM

    : RealDOM : 한 부분이 바뀌어도 전체 리스트를 reload 해야 함 

    : Virtual DOM : 한 부분이 바뀌어도 바뀐 부분 리스트만 update 해도 됨, snapshot을 이용해서 바뀐 부분을 관찰함

    - create-react-app으로 리액트 시작

    : 원래 리액트 앱을 처음 실행 하기 위해선 webpack이나 babel을 설정해야함

    : babel - 최신 자바스크립트 문법을 지원하지 않는 브라우저들을 위해서 최신 자바스크립트 문법을 구형 브라우저에서도 돌수있게 변형시켜줌

    : webpack - webpack을 이용해서 bundle화

    - npx create-react-app . 

    : 원래 npm을 이용하여 다운받을 때는 global 디렉토리에 다운받았음

    : npx는 npm registry에서 create-react-app을 찾아서 다운로드 없이 실행시켜줌, disk space를 낭비하지 않고

    항상 최신 버전을 사용할 수 있음

    - 페이지 이동을 할때 React Router Dom을 사용함 

    - 폴더별로 나누어 관리

    App.js

    - react-router-dom v6 버전에서 Switch 대신 Routes 사용

    - 랜딩시키고자 하는 페이지들을 폴더별로 분류한 후 import해서 사용함

    import './App.css';
    import React from 'react'
    
    import {
      BrowserRouter as Router,
      Routes,
      Route,
      Link
    } from "react-router-dom";
    
    import LandingPage from './components/views/LandingPage/LandingPage';
    import LoginPage from'./components/views/LoginPage/LoginPage';
    import RegisterPage from './components/views/RegisterPage/RegisterPage';
    
    function App() {
      return (
        <Router>
        <div>
        <Routes>
    
          <Route path="/register" element={<RegisterPage />}/>
          <Route path="/login" element={<LoginPage />} />
          <Route path="/" element={<LandingPage />} />
        </Routes>
          
        </div>
      </Router>
      );
    }
    
    
    
    export default App;

     

    LandingPage/LandingPage.js

    - 다른 페이지도 같은 방식으로 구성됨

    import React from 'react'
    
    function LandingPage() {
        return (
        <div>
            LandingPage 랜딩페이지
        </div>
        )
    }
    
    export default LandingPage

    <server -client 통신 test>

    - Axios install

    server/index.js

    app.get('/api/hello', (req, res) => {
    
        res.send("안녕하세요 ~ ")
    })

    client : LandingPage/LandingPage.js

    - 랜딩페이지 : react 키자마자 띄워지는 창 

    import React, {useEffect} from 'react'
    import axios from 'axios'
    import { response } from 'express'
    
    function LandingPage() {
        //랜딩페이지에 들어오자마자 실행 get request
        useEffect(() => {
            axios.get('/api/hello') //서버에 보냄
            .then(response => console.log(response.data)) //서버에서 돌아오면 콘솔창에 받은것을 보여줌
    
    
        })
        return (
        <div>
            LandingPage 랜딩페이지
        </div>
        )
    }
    
    export default LandingPage

    - 하지만! client와 server의 port번호가 다른데, 이는 Crocs 정책 때문에 통신이 불가능하다.

    - 만약 다른곳(port번호 다름)에서 request가 들어오면 crocs 보안 정책 때문에 request를 받을 수 없다.

    - 해결하는 방법은 다양하지만 , 여기서는 proxy방식을 이용함!

    - npm install http-proxy-middleware --save

    src/setupProxy.js

    - 서버 port : 5000번

    - 클라이언트 port : 3000번

    - 3000번 포트에서 오는 req을 5000번 서버가 받도록 함

    const { createProxyMiddleware }= require('http-proxy-middleware');
    module.exports = function(app) {
        app.use(
            '/api',
            createProxyMiddleware({
                target: 'http://localhost:5000',
                changeOrigin:true,
            })
        )
    }

    client/LandingPage.js

    import React, {useEffect} from 'react'
    import axios from 'axios'
    
    function LandingPage() {
        //랜딩페이지에 들어오자마자 실행 get request
        useEffect(() => {
            axios.get('/api/hello') //서버에 보냄
            .then(response => console.log(response)) //서버에서 돌아오면 콘솔창에 받은것을 보여줌
    
    
        }, [])
        return (
        <div>
            LandingPage 랜딩페이지
        </div>
        )
    }
    
    export default LandingPage

    server/index.js

    - 서버가 /api/hello에서 req을 받으면 res로 해당 문장을 출력함

    app.get('/api/hello', (req, res) => {
    
        res.send("안녕하세요 ~ ") //프론트로 responese 보냄
    })

    <Proxy Server>

    <Concurrency 로 서버랑 프론트 한번에 켜기>

    - 지금까지는 2개의 터미널에 따로 따로 켰음..

    - npm install concurrently

    - package.json 파일에 다음 값 입력하기

        "dev":"concurrently \"npm run backend\" \"npm run start --prefix client\""

    <CSS Framework>

    - 여러개 있지만, Ant Design 사용 예정

    - install antd


    <Redux>

    - 상태 관련 라이브러리

    - Props

    property의 줄임말

    컴포넌트 간 주고 받을때는 prop이용
    부모 컴포넌트에서 자식 컴포넌트로 보낼수 있음
    props는 변할 수 없음(변경하고 싶으면 부모에서 바꿔서 받아야함)

    - State

    부모 컴포넌트에서 자식에 전달하지 않음

    컴노넌트 안에서 데이터를 전달 교환하려면 state쓰기
    컴포넌트 안에서 state변하게 할 수 있음

    훨씬 편한 state 관리
    한방향으로만 흐름

    - action은 무엇이 일어났는지 설명하는 객체 ( 상태를 알려줌 )

    - reducer는 이전 state과 acton 객체를 받아, 변한 state를 리턴함

    - store는 appplication의 state을 감싸주는 역할

    - store안 여러 method 이용해 state을 관리함

    - store의 state을 변경하고 싶으면 dispatch이용해서 action으로 변경시킴

    - action은 객체 형식으로만 받는게 아니라 promise, function 형식으로 받을 수 있는데, redux-thunk, redux-promise

    이용해서 받게 됨 (미들웨어)

    client/index.js

    - redux 와 react를 연결

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    
    import { Provider} from 'react-redux';
    import 'antd/dist/antd.css';
    import { applyMiddleware, createStore} from 'redux';
    import promiseMiddleware from 'redux-promise';
    import ReduxThunk from 'redux-thunk'
    import Reducer from './_reducers'
    
    //미들웨어 연결(promise, functions)
    const createStoreWithMiddleware = applyMiddleware(promiseMiddleware,ReduxThunk)(createStore)
    
    
    ReactDOM.render(
      <Provider
        store={createStoreWithMiddleware(Reducer,
          
          window.__REDUX_DEVTOOLS_EXTENSION__ && //툴이용해서 redux 편리하게 이용하기 위함
          window.__REDUX_DEVTOOLS_EXTENSION__()
          )}
      
      >
        <App />
      </Provider>,
      document.getElementById('root')
    );
    
    reportWebVitals();

    _reducers/index.js

    - combineReducer

    : reducer는 state에 따라 여러가지로 나뉠 수 있다. 예를 들어 User Reducer, Post Reducer, Number Reducer .. 등등

    모두 combineReduce 이용해서 하나로 합쳐주기

    - reducer마다 폴더를 만들고 그 안에 파일을 만들어 import하면 됨

    import { combineReducers } from 'redux';
    import user from './user_reducer';
    //import comment from './comment_reducer';
    
    const rootReducer = combineReducers({
        user,
        //comment
    })
    
    export default rootReducer;

    - funtional component 는 간단하고 빠르지만 대신 한계가 많음

    - React Hooks 발표! functional component에서도 한계를 극복하게 됨

Designed by Tistory.