Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

wintertreey 님의 블로그

라우터 Router 연습_이미지넣기, 구구단, db자료 ajax. 부트스트랩. 본문

React

라우터 Router 연습_이미지넣기, 구구단, db자료 ajax. 부트스트랩.

wintertreey 2024. 8. 1. 09:24

이번 기회에 부트스트랩을 도입해보려고 한다. 

리액트에서는 쉽게 부트스트랩 css 파일을 통한 적용이 가능하다. 

 

1. 부트스트랩 설치

터미널에 다음 명령어를 사용하여 부트스트랩을 설치한다.

npm install bootstrap

 

2. 부트스트랩 CSS 파일을 import

src/index.js 또는 src/App.js 파일에 다음을 추가하여 부트스트랩 CSS 파일을 import한다.

이때 다른 <link> 파일에는 굳이 import 를 해주지 않아도 된다. 

import 'bootstrap/dist/css/bootstrap.min.css';

 

3. 그다음 부트스트랩 사이트를 참고하여 <>각 태그의 className에 소스를 추가해주면된다.

 

라우터 연습을 하면서 확인해보자.

 

App.js

import React from "react";
import {BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import 'bootstrap/dist/css/bootstrap.min.css'; // 부트스트랩 CSS 가져오기


import Main from "./menubar/Main";
import Gugudan from "./menubar/Gugudan";
import JikwonAjax from "./menubar/JikwonInfo";

function App() {
  return (
    <Router>
      <div className="container mt-4">
      <h2 className="mb-4">라우팅 문제</h2>
      <nav className="nav nav-tabs">
        <div className="nav-item">
        <Link className="nav-link" to ="/">메인화면</Link> 
        </div>
        <div className="nav-item">
        <Link className="nav-link" to ="/gugu">구구단</Link>
        </div>
        <div className="nav-item">
        <Link className="nav-link" to ="/jikwon">직원정보(ajax)</Link>
        </div>
      </nav>
      <Routes>
      <Route path="/" element={<Main/>}></Route>
      <Route path="/gugu" element={<Gugudan/>}></Route>
      <Route path="/jikwon" element={<JikwonAjax/>}></Route>
      </Routes>
      </div>

    </Router>
    
  );
}

export default App;

 

nav 의 className="nav nav-tabs"

이 부트스트랩 소스의 효과로 메뉴탭모양과 마우스오버시 해당 탭에 칸이 활성화 되는것을 확인할 수 있다.

 

메인화면 

import React from "react";
import pic from '../olaf.png';

const Main = () => {
    let st = {color: 'skyblue'}

    return (
    <div>
    <h3 style={st}>초기화면</h3>
    <img src = {pic} alt="첫번째 이미지"/>
    {/* img elements must have an alt prop*/}
    </div>
    );
}

export default Main;

 

예쁘게 출력하고자

제목에 css효과를 주었고 

이미지를 삽입해주었다. 

 

alt="첫번째 이미지"

alt가 하는일이 없다고 생각해 지웠더니 에러발생. 에러의 문구는 다음과 같았다.

img elements must have an alt prop

필수이다. 적어주자!

 

구구단

import React, { useState } from "react";
//import 'bootstrap/dist/css/bootstrap.min.css'; // 부트스트랩 CSS 가져오기

const Gugudan = () => {
    const [inputValue, setInputValue] =useState(''); 
    const [guguDan, setGuguDan] = useState([]);

    //입력한 값 받기
    const getgugu = (e) => {
        setInputValue(e.target.value);
    }

    //구구단 계산 및 출력
    const guguFunc = () => {
        const num = inputValue;
        const results = [];
        for(let g =1; g<10; g++){
            results.push(`${num} * ${g} = ${num*g}`);
        }
        setGuguDan(results);
    }

    
    return(
        <div>
            <br/>
            단 입력 : <input type="number" value={inputValue} onChange={getgugu}/>
            <button className="btn btn-outline-info" onClick={guguFunc}>확인</button>
            <br/>
            <h3>구구단</h3>
            <ul className="list-group mt-2">
            {guguDan.map((result, index) => (
                <li className="list-group-item" key={index}>{result}</li>
            ))}
            </ul>
        </div>
    );
}

export default Gugudan;

 

두 개의 이벤트 핸들러를 만들어주었다. 

텍스트칸에 적는 값을 받아주는, 그리고 해당 값으로 구구단을 계산하고 출력하는. 

 

두 개의 기능을 통합해 하나의 이벤트 핸들러로 만들어주는것도 생각해보았다. 

 

만약 입력값의 변경과 구구단계산을 하나의 함수로 처리한다면 장단점은 다음과 같다.

장점

코드 간결성.

일관성: 입력 값이 변경되면 자동으로 구구단을 업데이트하는 방식으로, 사용자 입력에 대한 응답성을 높일 수 있다.

단점

가독성: 한 함수에서 너무 많은 작업을 처리하면 코드가 복잡해질 수 있다. 특히 큰 함수는 유지보수가 어려울 수 있다.
성능: 입력값이 변경될 때마다 구구단 계산을 수행하면 불필요한 계산이 발생.

 

그래서 분리를 유지하기로 했다. 

 

 

for문으로 입력값을 출력하는 코드를 이용하여 구구단을 출력하였다. 

배열로 가지고 오는 값들을 받아올때는 map()함수를 이용한다.

 

부트스트랩을 적용하여 

버튼의 모양과 색을 변경하였다. 

또한 구구단 출력부분을 다듬어주었다. 

 

 

 

DB자료를 json형태로 받아, ajax의 방법으로 출력하기

import React, {useState, useEffect} from "react";
//import 'bootstrap/dist/css/bootstrap.min.css'; // 부트스트랩 CSS 가져오기

const JikwonAjax = () => {
    const [error, setError] = useState(null);
    const [isLoaded, setIsLoaded] = useState(false);
    const [info, setInfo] = useState([]);

    useEffect(() => {
        fetch("/wpro2/JikwonInfo.jsp", {method:"GET"})
        .then(res => {
            if(!res.ok){
                throw new Error('network does not response');
            }
            return res.json();
        })
        .then(
            (result) => {
                setIsLoaded(true);
                setInfo(result.jikwonInfo);
            },
            (error) => {
                setIsLoaded(true);
                setError(error);
            }
        )

    }, []);

    if(error){
        return <div>에러발생: {error.message}</div>
    }else if(!isLoaded){
        return <div>자료 수신중</div>
    }else{
        return(
            <>
            <br/>
               <table class="table table-striped">
               <thead class="table-dark">
                <tr>
                    <th>사번</th><th>직원명</th><th>부서명</th><th>직급</th>
                </tr>
                </thead>
                <tbody>
                {info.map(jinfo => (
                <tr key={jinfo.jikwon_no}>
                    <td>{jinfo.jikwon_no}</td><td>{jinfo.jikwon_name}</td><td>{jinfo.buser_name}</td><td>{jinfo.jikwon_jik}</td>
                </tr> 
                 ))}
                </tbody>
               </table>
               <div>
                인원수 : {info.length}명
               </div>
            </>
        );
    }
}

export default JikwonAjax;

 

우선 이클립스에서 자료를 출력해야한다.

 

 

JikwonInfo.jsp

<%@page import="javax.servlet.jsp.tagext.TryCatchFinally"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.Connection"%>

<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
{"jikwonInfo":[
<%

Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;

try{
	Class.forName("org.mariadb.jdbc.Driver");
	String Url ="jdbc:mariadb://localhost:3306/test";
	conn = DriverManager.getConnection(Url, "root", "123");
	pstmt = conn.prepareStatement("select jikwon.jikwon_no, jikwon.jikwon_name, buser.buser_name, jikwon.jikwon_jik from jikwon inner join buser on jikwon.buser_num=buser.buser_no");
	rs = pstmt.executeQuery();
	
	String result = "";
	
	while(rs.next()){
		result += "{";
		result += "\"jikwon_no\":" + "\"" + rs.getInt("jikwon_no") + "\",";
		result += "\"jikwon_name\":" + "\"" + rs.getString("jikwon_name") + "\",";
		result += "\"buser_name\":" + "\"" + rs.getString("buser_name") + "\",";
		result += "\"jikwon_jik\":" + "\"" + rs.getString("jikwon_jik") + "\"";
		result += "},";
	}
	if(result.length() > 0){
		result = result.substring(0,result.length() - 1);
		// 전체 길이 - 1만큼만 반환 
	}
	out.print(result);
}catch(Exception e){
	System.out.println("에러 : " + e);
	
}finally{
	try {
		rs.close();
		pstmt.close();
		conn.close();
	}catch (Exception e){
		
	}
}
%>
]
}

s가져올 칼럼은 사번, 직원명, 부서명, 직원직급이다. 

가져올 db에 맞는 sql문을 작성하자.

 

 

'React' 카테고리의 다른 글

error : npm 인식 문제  (0) 2024.08.04
React Life Cycle_ 디지털 시계. Form 작업  (0) 2024.08.01
라우터 Router  (2) 2024.08.01
투두리스트. 단위환산계산기.  (0) 2024.08.01
React.memo()  (0) 2024.08.01