100일 챌린지/빅데이터기반 인공지능 융합 서비스 개발자

Day 79 - React로 CRUD 프로그램 만들기 (3) Nodejs API 서비스 이용

ksyke 2024. 11. 20. 17:48

목차

    API 프로젝트 만들기

    app.js

    var createError = require('http-errors');
    var express = require('express');
    var path = require('path');
    var cookieParser = require('cookie-parser');
    var logger = require('morgan');
    var cors = require('cors');
    
    var indexRouter = require('./routes/index');
    var usersRouter = require('./routes/users');
    
    var app = express();
    
    // view engine setup
    // app.set('views', path.join(__dirname, 'views'));
    // app.set('view engine', 'jade');
    
    var corsOptions = {
      origin: 'http://localhost:3000',
      optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
    }
    
    app.use(cors(corsOptions));
    app.use(logger('dev'));
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    app.use(cookieParser());
    app.use(express.static(path.join(__dirname, 'public')));
    
    // app.use('/', indexRouter);
    // app.use('/users', usersRouter);
    app.use('/dept',require('./routes/dept'));
    
    // catch 404 and forward to error handler
    app.use(function(req, res, next) {
      next(createError(404));
    });
    
    // error handler
    app.use(function(err, req, res, next) {
      // set locals, only providing error in development
      res.locals.message = err.message;
      res.locals.error = req.app.get('env') === 'development' ? err : {};
    
      // render the error page
      res.status(err.status || 500);
      res.render('error');
    });
    
    module.exports = app;

    dept.js

    const mysql = require('mysql2');
    const express =require('express');
    const router=express.Router();
    const info={
        host: 'localhost',
        user: 'scott',
        password: 'tiger',
        database: 'xe'
      };
    
    router.get('/',(req,res)=>{
        const connection = mysql.createConnection(info);
        connection.connect();
        connection.query('select * from dept', (err, rows, fields) => {
              if (err) throw err
              res.json({'result':rows});      
        });
        connection.end();
    });
    
    router.post('/',(req,res)=>{
        const {deptno,dname,loc}=(req.body);
        const connection = mysql.createConnection(info);
        connection.connect();
        connection.query('insert into dept values (?)',[[deptno,dname,loc]], (err, rows, fields) => {
              if (err) throw err
              res.status(201);
              res.end();
        });
        connection.end();
    });
    
    router.get('/:deptno',(req,res)=>{
        const {deptno}=(req.params);
        const connection = mysql.createConnection(info);
        connection.connect();
        connection.query(`select * from dept where deptno=${deptno}`, (err, rows, fields) => {
              if (err) throw err
              res.json({...rows[0]});   
        });
        connection.end();
    });
    
    module.exports=router;


    FrontEnd 프로젝트 만들기

    Frame.js

    import React, { useState } from 'react'
    import { Link, NavLink, Outlet } from 'react-router-dom'
    
    function Frame() {
    
        const [menu,setMenu]=useState(false);
    
      return (
        <>
        {/* 메뉴 */}
        <nav class="navbar navbar-default">
            <div class="container-fluid">
                <div class="navbar-header">
                <Link class="navbar-brand" to="#">
                    인제대학교
                </Link>
                </div>
                <ul class="nav navbar-nav">
                    <li className={menu=='Home'?'active':''}><NavLink className={({ isActive }) =>
                            {if(isActive){setMenu('Home');}}
                        } to='/'>Home </NavLink></li>
                    <li className={menu=='Intro'?'active':''}><NavLink className={({ isActive }) =>
                            {if(isActive){setMenu('Intro');}}
                        } to='/intro'>Intro</NavLink></li>
                    <li className={menu=='Dept'?'active':''}><NavLink className={({ isActive }) =>
                            {if(isActive){setMenu('Dept');}}
                        } to='/dept/'>Dept</NavLink></li>
                </ul>
            </div>
        </nav>
        {/* 컨텐츠 */}
        <div className='container'>
            <div className='content'>
                <Outlet/>
            </div>
            <div className='footer'>
                <p>김해캠퍼스 (50834) 경남 김해시 인제로 197</p>
                <p>Copyright(c) 1996-2022 INJE University. All rights reserved.</p>
            </div>
        </div>
        </>
      )
    }
    
    export default Frame

    Main.js

    import React from 'react'
    
    function Main() {
      return (
        <div className='jumbotron'>
            <h2>환영합니다.</h2>
        </div>
      )
    }
    
    export default Main

    Intro.js

    import React,{Image} from 'react'
    
    function Intro() {
      return (
        <div>
            <img src='https://www.inje.ac.kr/kor/assets/images/sub/gimhae-campus-1-241008.jpg'/>
        </div>
      )
    }
    
    export default Intro

    Depts.js

    import React, { Suspense, useEffect, useState } from 'react'
    import { Link } from 'react-router-dom'
    // import Row from './components/Row';
    const Row=React.lazy(()=>import('./components/Row'));
    
    function Depts() {
    
        const [arr,setArr]=useState([]);
    
        useEffect(()=>{
            fetch('http://localhost:3030/dept/')
            .then(res=>res.json())
            .then(json=>{
                console.log(json.result);
                setArr([...json.result]);
            }).catch(e=>alert(e));
        },[]);
    
      return (
        <>
            <h2 className='page-header'>List page</h2>
            <div class="list-group">
                <div className="list-group-item active">
                    <h4 class='list-group-item-heading'>DNAME</h4>
                    <p>LOCATION</p>
                </div>
                <Suspense fallback={<h3>로딩중...</h3>}>
                    {arr.map(ele=><Row dname={ele.dname} loc={ele.loc} deptno={ele.deptno}/>)}
                </Suspense>
            </div>
        </>
      )
    }
    
    export default Depts

    Row.js

    import React from 'react'
    import { Link } from 'react-router-dom'
    
    function Row({dname,loc,deptno}) {
      return (
        <Link to={"/dept/"+deptno} className="list-group-item">
            <h4 class="list-group-item-heading">{dname}</h4>
            <p class="list-group-item-text">{loc}</p>
        </Link>
      )
    }
    
    export default Row

    DeptAdd.js

    import React, { useRef, useState } from 'react'
    import { useNavigate } from 'react-router-dom'
    import FormInput from './components/FormInput';
    
    function DeptAdd() {
      const [inputVals,setInputVals]=useState({deptno:'',dname:'',loc:''});
      const navigate=  useNavigate();
      const refInp1=useRef();
      const refInp2=useRef();
      const refInp3=useRef();
      const deptSend=e=>{
        e.preventDefault();
        fetch('http://localhost:3030/dept/',{
            method:'POST',
            body:JSON.stringify({deptno:refInp1.current.value,dname:refInp2.current.value,loc:refInp3.current.value}),
            headers:{
                'Content-Type':'application/json'
            }
        }).then(e=>{
            if(e.ok) 
                navigate('/dept/');
        }).catch(err=>{
            alert(err);
        });
    
      };
    //   const editVal=e=>{
    //     if(e.target.name=='deptno')
    //         setInputVals({...inputVals,deptno:e.target.value});
    //     if(e.target.name=='dname')
    //         setInputVals({...inputVals,dname:e.target.value});
    //     if(e.target.name=='loc')
    //         setInputVals({...inputVals,loc:e.target.value});
    //   };
      return (
        <>
            <h2 className='page-header'>입력 페이지</h2>
            <form onSubmit={deptSend}>
                {/* 
                <FormInput ref={refInp1} name='deptno' val={inputVals.deptno} editVal={editVal}/>
                <FormInput ref={refInp2} name='dname' val={inputVals.dname} editVal={editVal}/>
                <FormInput ref={refInp3} name={'loc'} val={inputVals.loc} editVal={editVal}/> 
                */}
    
                <FormInput ref={refInp1} name='deptno'/>
                <FormInput ref={refInp2} name='dname'/>
                <FormInput ref={refInp3} name={'loc'}/>
                <div className='form-group'>
                    <button type='submit' className='btn btn-primary btn-block'>입력</button>
                    <button type='reset' className='btn btn-default btn-block'>취소</button>
                    <button type='button' className='btn btn-default btn-block' onClick={navigate(-1)}>뒤로</button>
                </div>
            </form>
        </>
      )
    }
    
    export default DeptAdd

    FormInput.js

    import React, { useState } from 'react'
    
    function FormInput({ref,name}) {
        const [val,setVal]=useState('');
        return (
        <div className='form-group'>
            <input ref={ref} name={name} placeholder={name} value={val} onChange={e=>{setVal(e.target.value)}} className='form-control'/>
        </div>
      )
    }
    
    export default FormInput

    Dept.js

    import React, { useEffect } from 'react'
    import { useParams } from 'react-router-dom'
    
    function Dept() {
        const {deptno}=useParams();
        useEffect(()=>{
        });
      return (
        <>
        <h2>Dept detail <small>deptno:{deptno}</small></h2>
    
        </>
      )
    }
    
    export default Dept

    index.js

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './css/bootstrap.min.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    import { BrowserRouter, Route, Routes } from 'react-router-dom';
    import Frame from './pages/components/Frame';
    import Main from './pages/Main';
    import Intro from './pages/Intro';
    import Depts from './pages/Depts';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      // https://react.dev/reference/react/StrictMode
      <React.StrictMode>
        <BrowserRouter>
          <Routes>
            <Route path='/' element={<Frame/>} >
              <Route index element={<Main/>} />
              <Route path='/intro' element={<Intro/>} />
              <Route path='/dept/' element={<Depts/>} />
            </Route>
          </Routes>
        </BrowserRouter>
      </React.StrictMode>
    );
    
    // If you want to start measuring performance in your app, pass a function
    // to log results (for example: reportWebVitals(console.log))
    // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
    reportWebVitals();