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 본문

React

라우터 Router

wintertreey 2024. 8. 1. 09:24

라우터란?

사용자가 요청한 URL에 따라 해당 URL에 맞는 페이지를 보여주는 것이라고 생각하면 된다. 

리액트에서는 라우팅 관련 라이브러리가 많은데, 이중 가장 많이 쓰이는 React Router 활용.

 

리액트는SPA (Single Page Application) 방식

 - 기존 웹 페이지 처럼(MPA 방식) 여러 개의 페이지를 사용, 새 페이지를 로드하는 방식이 아니다.

 - 새 페이지를 로드 하지 않고 하나의 페이지 안에서 필요한 데이터만 가져오는 형태를 가진다.

React-Router는 신규 페이지를 불러오지 않는 상황에서 각각의 url에 따라 선택된 데이터를 하나의 페이지에서 렌더링 해주는 라이브러리라고 할 수 있다.

 

라우터를 사용하기 전에 설치해줘야한다. 터미널에서 다음과 같이 명령문을 적어주자.

npm install react-router-dom 

 

 

 


 

App.js

import React from "react";
import {BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";

import MyTest from "./exam/Test";
import HiAbout from "./exam/About";
import Counter from "./exam/Counter";
import Input1 from "./exam/Input1";
import Input2 from "./exam/Input2";
import Multidata from "./exam/Multidata";
import MyAjax from "./exam/MyAjax";

function App() {
  return (
    <Router>
    <div className="App">
     <h2>라우트 연습용 메인 화면</h2>
    <MyTest/>
    <hr/>
    {/* 메뉴 작성 : 라우팅 연습*/}
    <nav>
     
      <Link to="/">Test 화면</Link> | 
      <Link to="/about">About 보기</Link> | 
      <Link to="/kkount">친구추가및삭제</Link> | 
      <Link to="/input1">자료입력1</Link> | 
      <Link to="/input2">자료입력2</Link> | 
      <Link to="/multi">배열자료</Link> | 
      <Link to="/ajax">Ajax 요청</Link>
    </nav> 
      <Routes>
      <Route path="/" element={<MyTest/>}></Route>
      <Route path="/about" element={<HiAbout/>}></Route>
      <Route path="/kkount" element={<Counter/>}></Route>
      <Route path="/input1" element={<Input1/>}></Route>
      <Route path="/input2" element={<Input2/>}></Route>
      <Route path="/multi" element={<Multidata/>}></Route>
      <Route path="/ajax" element={<MyAjax/>}></Route>
      </Routes>
    </div>
    </Router>
  );
}

export default App;

 

<Link>

a 태그로 전환되며,요청명 개념으로 이해하면 된다. 요청하는 쪽. 

 

<Route>

컴포넌트에서 동적 라우팅 구현 가능하다. 요청을받는쪽.

test화면 링크를 누르면, route path / 와 매핑되고,
실질적으로 실행될 컴포넌트는 element에 적혀있는 <MyTest>이다. 

 

 

하이퍼링크처럼 구현된부분을 누르면, 새로고침없이 화면이 부분적으로 수정되어 내용이 바뀌어 나타난다.

 

 

 

버튼효과

import React, {useState} from "react";

const Counter = () => {
    const [member, setMember] = useState(0);

    const increase = () => {
        setMember(member +1); //member +=1
    }

    const decrease = () => {
        setMember(member -1); //member -=1
    }

    return(
        <div>
            <br/><br/>
            <button onClick={increase}>친구추가</button>&nbsp;&nbsp;
            <button onClick={decrease}>친구삭제</button>
            <p>친구수는 {member}</p>
        </div>
    );

}
export default Counter;

 

 

 

 

 

텍스트입력값 보여주기

import React, {useState} from "react";

const Input1 = () => {
    const [txtValue, setTxtValue] = useState('');

    const changeFunc = (e) => {
        setTxtValue(e.target.value);
    }
    return(
        <div>
            <input type="text" value={txtValue} onChange={changeFunc}></input>
            <br/>
            입력값 : {txtValue}
        </div>
    );
}

export default Input1;
import React, {useState} from "react";

const Input2 = () => {
    const [params, setParams] = useState({
        irum: '',
        nai: '', 
        juso: ''
    });

    const {irum, juso, nai} = params;

    const changeFunc = (e) => {
        const value = e.target.value;
        const id = e.target.id;

        setParams({ //js 연산자
            ...params, 
            [id]:value //에러방지용으로 작성. ?
        })

    }
  
    return(
        <div>
            <br/>
            <div>
                <lable for = "irum">이름: </lable>
                <input type="text" value={irum} id="irum" onChange={changeFunc}/>
            </div>  
            <div>
                <lable for = "nai">나이: </lable>
                <input type="text" value={nai} id="nai" onChange={changeFunc}/>
            </div>  
            <div>
                <lable for = "juso">주소: </lable>
                <input type="text" value={juso} id="juso" onChange={changeFunc}/>
            </div>  
        <br/>
        <h3>처리 결과</h3>
        <table>
        <tr>
            <td>이름은 {irum}</td>
            <td>나이는 {nai}</td>
            <td>주소는 {juso}</td>
        </tr>
        </table>
        </div>
    );
}

export default Input2;

 

 

 

여기서 드는 의문점. setParams

 


const [params, setParams] = useState({

    irum:'',

    nai:'',

    juso:''

});

 

const [params, setParams]:     배열 디스트럭처링을 사용하여 상태 변수 (params)와 그 상태를 업데이트하는 함수 (setParams)를 선언한다.

useState:      React Hook으로, 상태를 초기화한다. 초기 상태를 인수로 받음.

{ irum: '', nai: '', juso: '' }:       초기 상태 객체로, 세 가지 속성(irum, nai, juso)을 모두 빈 문자열로 초기화한다.

 

* 상태 디스트럭처링 : 구조분해할당(destructuring assignment)

const { irum, juso, nai } = params;

const { irum, juso, nai }:     객체 디스트럭처링을 사용하여 params 상태 객체에서 irum, juso, nai 속성을 추출한다.

= params:      params 객체에서 irum, juso, nai 값을 각각의 변수에 할당한다.

 

setParams

setParams 함수 호출: setParams 함수는 새로운 상태 객체를 인수로 받는다.

새로운 객체 생성: setParams 함수에 전달되는 객체는 다음과 같이 구성된다:

{

    ...params,

    [id]: value

}


 

배열자료 출력하기

 

배열자료를 출력할 경우, map()함수를 이용한다.

import React from "react";

// Member 컴포넌트
const Member = ({memberData}) => {
    return(
        <tr>
            <td>{memberData.irum}</td>
            <td>{memberData.junhwa}</td>
        </tr>
    );

}

// 메인 컴포넌트
const Multidata = () => {
    const members = [
        {irum:'관우', junhwa:'111-1111'},
        {irum:'장비', junhwa:'222-1111'},
        {irum:'유비', junhwa:'333-1111'}
    ];

    return(
        <table>
            <thead>
            <tr>
                <th>이름</th><th>전화</th>
            </tr>
            </thead>
            <tbody>
                {/*배열렌더링시 각 요소 고유key를 추가 */}
                {members.map((mem, index) => (
                    <Member key={index} memberData={mem} />
                ))}
            </tbody>
        </table>
    );
}

export default Multidata;

 

 

 

 

ajax를 이용하여 jsp자료 읽기

 

이클립스에서 jsp파일 하나를 만들었다.

<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
{
"fruits":[
	{"code":1, "name":"수박", "price":"25000"},
	{"code":2, "name":"복숭아", "price":"1200"}
]

}

 

이를 이클립스에서 아파치 톰캣 서버를 이용해 웹상에 띄운다. 

 

 

 

이클립스에서 아파치톰캣 서버 계속 켜두어 살려두어야 해당 자료를 읽어올 수 있다. 

이클립스 서버의 포트번호는 8080, vs code 서버의 포트번호는 3000.

 

이는 SOP (same origin policy, 동일 출처 정책)의 정책에 위배되며, 원론적으로는 리소스를 읽어오는것이 불가능하다.

나에게 똥을 주다니..!

 

 

다른 출처의 리소스가 필요하다면?

그때 사용하는게 cors(cross origin resource sharing 교차 출저 리소스 공유)이다. 

A server <> B server 는 cors 에러가 나지 않는다.

 

따라서 package.json에 proxy 부분을 추가해줘야한다.

 

추가해준 모습

 

 

ajax를 이용해 자료를 읽어받아올경우, useEffect를 반드시 사용할 수 밖에 없다. 

 

useEffect

부수 효과(side effects)를 수행하는 데 사용된다. 데이터 가져오기, 구독 설정, 수동 DOM 조작 등을 처리할 수 있다.

import React, {useState, useEffect} from "react";

const MyAjax = () => {
    const [error, setError] = useState(null);
    const [isLoaded, setIsLoaded] = useState(false);
    const [items, setItems] = useState([]);


    useEffect(() => {
        fetch("/web_react/abc.jsp", {method:'GET'})
        .then(res => {
            if(!res.ok){
                throw new Error('network response was not ok');
            }
            return res.json();
        })
        .then(
            (result) => {
                setIsLoaded(true);
                setItems(result.fruits); //fruits 받아오는자료값의 fruits. 상단useState와무관
            },
            (error) => {
                setIsLoaded(true);
                setError(error);
            }
        )
    }, []);

    
    if(error){
        return <div>에러: {error.message}</div>
    }else if(!isLoaded){
        return <div>자료 수신중</div>
    }else{
        return(
            <ul>
                {items.map(fitem => (
                    <li>
                        {fitem.code} {fitem.name} {fitem.price}
                    </li>
                ))}
            </ul>
        );
    }


}

export default MyAjax;

 

fetch를 이용해 jsp 자료(Apache server) 읽는다.

 

useEffect 시
Ajax 처리 성공하면 isLoaded, items갱신. 실패하면 error 갱신.

 

error가 나면 에러메시지를, isLoaded가 false이면 로딩메시지 보이기
그외의 경우 items를 출력(rendering)한다.

 

 

 

 


https://cafe.daum.net/flowlife/QbpR/73

https://cafe.daum.net/flowlife/QbpR/75