반응형

이전에는 리엑트를 연습했엇다.

이제 본격적으로 리엑트 + 스프링 부트를 한번 연결 시켜 보자 

 

인텔리 제이로했음 .

 

JSX로 함

 

우선 컨트롤러를 보자 

 

@RestController
public class boardController {

    @GetMapping("/board")
    public String board() {
        System.out.println("연결 잘됨?");
        return "연결테스트";
    }

    }

 

이렇게 /board라는 것을 use이펙터로 

ajax를 사용 하여 컨트롤러와 통신한다. 

 

import logo from './logo.svg';
import './App.css';
import { useEffect, useState } from 'react';
import axios from 'axios';

function App() {
  // message 초기값 설정 (""로 설정)
  const [message, setMessage] = useState("");

  // useEffect(함수, 배열) : 컴포넌트가 화면에 나타났을 때 자동 실행
  useEffect(() => {
    // fetch(url, options) : Http 요청 함수
    fetch("/board")
      .then(response => response.text())
      .then(message => {
        setMessage(message);
      });
  }, [])

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          board : {message}
        </p>
      </header>
    </div>
  );
}

export default App;

 

 성공이다.

반응형
반응형

나는 SPA에서 어떻게 페이지 전환을 할까 궁굼했다. 

근데 라우터라는 것으로 가능하다고 한다.

 

알아보자.

 

https://reactrouter.com/

 

Declarative routing for React apps at any scale | React Router

Version 6 of React Router is here! React Router v6 takes the best features from v3, v5, and its sister project, Reach Router, in our smallest and most powerful package yet.

reactrouter.com

요기서 스타트를 해준다.

 

그다음 index.js에서

 

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
    <App />
    </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();

이렇게 BrowserRouter을 설정해주면 된다. 

 

문법은 다음과 같다. 

  <Routes> 
   <Route path='/(페이지명)' element={html소스}/>
  </Routes>

 

엘리먼트에는 컴포넌트를 만들어서 쓰면 좋다 .

 

예를 들면 About이라는 컴포넌트를 만들었다고 생각하자

 

function About(){
  return(
  <div>
    회사 정보임
    <Outlet></Outlet>
  </div>
  )

,

<Route path='/about' element={<About/>}>

엘리먼트 태그를 넣게되면 이렇게 나온다.

중첩도 가능하다

about/member 이런식으로 중첩

 

       <Route path='/about' element={<About/>}> 
          <Route path='member' element={<div>맴버임</div>}/>
          <Route path='location' element={<About/>}/>
        </Route>

 

이렇게 맴버임이 나온다.

 

애플코딩이라는 렉쳐를 통해 공부를 하고있는데

리엑트에 대해서 알아가는게 점점 성장하는것이 보인다. 

 

useState, props 등등 배운것을 항상 정리하자.

반응형
반응형

1) State 만드는법 

 

JS같은 경우는 let 변수명 = '저장 내용'같은 경우로 저장했엇는데 

리엑트에서는 변수 말고 state를 만들어서 데이터를 저장해둘 수 있다. 

 

 

const [fruit, setFruit] = useState({ color : "red", name : "apple" })

우선  import {useState} from 'react' 를 하고 

useFruit(저장할 내용)을 쓰면 된다. 

 

word자리에 state 이름은 자유롭게 작명 하면된다. 

1. 새로운 객체를 만들어서 setFruit 하는 방법

setFruit({ color:"red", name:"strawberry" })

2. fruit state를 이용하여 name만 변경하는 방법

setFruit({ ...fruit, name:"strawberry" })

3. prevState를 이용하여 이전 state 값을 사용하여 setState를 하는 방법

setFruit(prev => ({ ...prev, name:"strawberry" }))



2. Map 쓰는법 

 

모든 array 자료 우측엔 map() 함수를 붙일 수 있습니다.

자바스크립트 기본함수 같은건데 용도를 알아봅시다. 

 

var 어레이 = [2,3,4];
어레이.map(function(){
  console.log(1)
});

기능 1. array에 들어있는 자료갯수만큼 그 안에 있는 코드를 반복실행해줍니다.

저러면 진짜로 console.log(1) 3번 실행됨 

 

var 어레이 = [2,3,4];
어레이.map(function(a){
  console.log(a)
});

기능 2. 콜백함수에 파라미터 아무렇게나 작명하면

그 파라미터는 어레이 안에 있던 모든 자료를 하나씩 출력해줍니다.

(그냥 소괄호안에 있는 함수를 콜백함수라고 합니다)

저러면 진짜로 2, 3, 4가 콘솔창에 출력됨 

 

var 어레이 = [2,3,4];
var newArray = 어레이.map(function(a){
  return a * 10
});
console.log(newArray)

기능3. return 오른쪽에 뭐 적으면 array로 담아줍니다.

그리고 map() 쓴 자리에 남겨줍니다.

그래서 변수에 담아서 출력해봤더니 진짜로 array에 담아주긴 하는군요 

newArray는 [20, 30, 40] 이 출력됩니다. 

 

 

JSX안에서 반복문을 생성하고 싶으면

 

리엑트 중괄호안에서 html 반복생성하고 싶다면 map을 써도 된다. 

 

function App (){
  return (
    <div>
      { 
        [1,2,3].map(function(){
          return ( <div>안녕</div> )
        }) 
      }
    </div>
  )
}

 

map은 파라미터가 2개 까지 가능하다 

첫째 파라미터는 array안에 있던 자료

둘째 파라미터 i는 0부터 1씩 증가하는 정수를 나타냄

 

 

props 쓰는법

 

예를들어 모달을 띄우고 싶다면 

 

요론식으로 app안에 모달이 있다고 생각하자 컴포넌트를 먼저 만들어준다. 

 

자바의 상속같은 개념인데

 app -> modal쪽으로 스테이터스를 넘겨줄 수 있다. 

 

그방법은 다음과 같다. 

 

function app(){

	let [data, setData] = useState(0);
	
	<div>
    	<MODAL data={data }/>
    </div>
}

fucntion Modal(props){
	return(
    	<div>
        props.data
        </div>
    )
}

요론식으로 쓰면 data가 나온다.

 

부모 APP 

자식 Modal이다. 

 

자식 -> 부모 (x)

자식 -> 자식 (x)

 

안됨

 

https://moonseokhyun.github.io/

 

React App

 

moonseokhyun.github.io

 

다만 들었당 읭..

반응형
반응형

 오늘은 블로그 컴포넌트를 만들어보겠다. 

컴포넌트 만드는 방법은 다음과 같다. 

 

1. function을 만들고

2. return()에 html을 써준다.

3. <함수명> </함수명> 을 써주면 끝난다. 

 

function Modal(){
    return(
      <div className='modal'>
        <h4>제목</h4>
        <p>날짜</p>
        <p>상세내용</p>
      </div>
    )
}

이런 모달을 하나 만들었다.

 

      {
        // 조건식 ? 참일때 실행할 코드 : 거짓일 떄 실행할 코드 
        modal == true ? <Modal/> : null
      }

모달같은경우에는 평소에 안보여야 하니 

let [modal, setModal] = useState(false);

이런식으로 스테이터스를 만들어준다. 

 

리엑트를 공부할때 느꼇지만 신기했다. 

나는 제이쿼리로 HTML ID나 CLASS를 지목하고

display = none이나 

제이쿼리 hide() , show()

이런식으로 했는데 리엑트에서는 이런식으로 스위치 식으로 해야한다고 한다. 

 

파이선 독학 및 제목을 누르면

이렇게 나온다 !

 

 

반응형
반응형

 

지금 디비 연동 없는 리엑트 블로그 연습 중이다. 

오늘은 스테이트가 Array타입 일때 변경하는 법에 대해서 알아보자 

 

let [글제목, b] = useState(['남자 코트 추천','강남 맛집 추천' , '파이선독학']);

function s(){
  let copy = [...글제목]; //새로운 스테이트를 만들어 줘라.
  //기존 스테이트가 어레이나 오브젝트면 독립적 카피본을 만들어서 수정해야한다. 
  //왜 냐하면 copy과 글제목이 같기 때문에
  copy[0] = '여자코트 추천';
  console.log(copy == 글제목)
  b(copy);
}

<div className='list'>
        {/* 온클릭 안에는 항상 함수를 넣어야한다. */}
        <h4>{글제목[0]} <span onClick={likeUp}>👍</span> {like}
        <span onClick={s}> 추천</span>
        </h4> 
        <p>2월 17일 발행</p>
      </div>

추천 버튼을 누르면 여자코트변경으로 바뀌는 코드 이다. 

 

리엑트는 onclick={함수명}으로 onclick이 된다. 

 

함수를 우선 하나 만들어준다. 

그 뒤 Array를 카피할 변수하나를 만들어 준다. 

그리고 새로운 스테이터스를 만들기 위해 

...을 붙혀준다 .

...을 안 붙혀주면 글제목에 있는 변수가 그대로 불러와져 변경이 안된다. 

그리고 copy[0] 0번째 인덱스에 스트링타입으로 '여자코트 추천을 써준다.'

그리고 set글제목을 해주면 

추천을 누르면 변경된다. 

 

 

반응형
반응형
import logo from './logo.svg';
import './App.css';
import { useState } from 'react';

// return안에는 병렬로 태그 2개 이상 기입 금지



// 자료 잠깐 저장할 떈 변수
let post = '강남우동 맛집';

// 자료 잠깐 저장할땐 스테이트 문법


function App() {
let [글제목, b] = useState(['여자 코트 추천','강남 맛집 추천' , '파이선독학']);
// let [logo, setLogo] = useState('ReactBlog'); 무언가 변경이 되는것만 useState 쓰는법


  return ( 
    <div className="App">
      <div className="black-nav">
        <h4>ReactBlog</h4>
      </div>
      <div className='list'>
        <h4>{글제목[0]}</h4>
        <p>2월 17일 발행</p>
      </div>
      <div className='list'>
        <h4>{글제목[1]}</h4>
        <p>2월 17일 발행</p>
      </div>
      <div className='list'>
        <h4>{글제목[2]}</h4>
        <p>2월 17일 발행</p>
      </div>
    </div>
  );
}

export default App;

우선 기본 코드는 다음과 같다. 

 

APP.js라는 곳이 메인 html을 쓰는데 

return ( html  코드);

 

병렬로 2가지 이상 태그를 금지한다. 바로 에러남 . 

 

그리고

 

1) Class는 ClassName 으로 제공한다.

 

 

2) JSX에서 JSTL처럼 변수명을 하기가 편하다

 

ex) var name = '홍길동' 이 있다면

 

<p> 이름 : {name}</p>

이라고 하면

이름 : 홍길동 이라고 이름 이 저장된다. 

 

3) useState가 있다. 무언가 변경이 되는 것만 useState를 쓴다.

ex) logo 등 몇년에 한번 변경 되는건 변수선언을 한다. 

 

 

 

 

 

 

나중에 스프링부트 + 리엑트 한번 해봐야겠다.

 

ㄹㅇ 신세계다. 

저번에 JPA 부터 신세계 느끼는중..

반응형
반응형

1. 작업용 폴더를 하나 만들어 준다. 

 

2.

PowerShell 창을 연다. 

 

3. npx create-react-app [프로젝트명]

 

엔터를 해주면 파일이 막 다운로드 되면서 

대충 요로코롬 뜬다. 

 

이제 VSCODE에서 프로젝트를 연다 .

 

터미널에서 

 

npm Start를 쳐주면 완성

 

반응형
반응형

저번에는 페이징기능에 대해서 알아보았다 .

 

이번에는 간단한 검색기능을 알아보려고한다. 

 

검색이라는 걸 검색했는데 데이터가 없다 .

 

우선 인터페이스인 BoardRepository를 추가해야 된다. 

 

Page<Board> findByTitleContaining(String searchKeyword, Pageable pageable);

이렇게 추가해준다. 

 

searchKeyword는 검색어를 pageable는 페이징에대한 정보를 받는다. 

 

그다음 컨트롤러에 추가해주자

 

 

    @GetMapping("/board/list")
    public String boardList(Model model,
                            @PageableDefault(page = 0, size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable,
                            String searchKeyword) {

        Page<Board> list = null;

        if(searchKeyword == null) {
            list = boardService.boardList(pageable);
        }else {
            list = boardService.boardSearchList(searchKeyword, pageable);
        }

        int nowPage = list.getPageable().getPageNumber() + 1;
        int startPage = Math.max(nowPage - 4, 1);
        int endPage = Math.min(nowPage + 5, list.getTotalPages());

        model.addAttribute("list", list);
        model.addAttribute("nowPage", nowPage);
        model.addAttribute("startPage", startPage);
        model.addAttribute("endPage", endPage);

        return "boardlist";
    
    }

우선 Page<T> 제네릭으로 Board를 해주고  null을 표현해준다.

다음에 if문으로 검색어가 오지 않았을때 페이징처리만해주고 

검색어가 왔을 경우 검색어 + 페이징처리를 해준다. 

 

<th:block th:each="page : ${#numbers.sequence(startPage, endPage)}">
    <a th:if="${page != nowPage}" th:href="@{/board/list(page = ${page - 1}, searchKeyword = ${param.searchKeyword})}" th:text="${page}"></a>
    <strong th:if="${page == nowPage}" th:text="${page}" style="color : red"></strong>
</th:block>
<form th:action="@{/board/list}" method="get">
    <input type="text" name="searchKeyword">
    <button type="submit">검색</button>
</form>

 

 

 

${param.name} 
으로 받을수 있다.

param 은 파라미터값으로 넘어온 데이터를 뜻하고
name 은 그 데이터중 name이라는 이름을 갖는 데이터의 값을 가져오겠다는 뜻이다.

뷰를 보면 form태그를 통해 검색어를 컨트롤러에 태운다.

그다음에 searchKeyword로 ${param}으로 잡아서 넣어준다. 

 

이렇게 CRUD + 페이징 + 검색까지 기본적인 공부는 끝난거같다.

다음에는 JS를 공부하고 리엑트를 공부해서 

 

스프링부트 + 리엑트 프로젝트를 해보자

 

https://github.com/MoonSeokHyun

 

MoonSeokHyun - Overview

http://mls0000.dothome.co.kr/. MoonSeokHyun has 14 repositories available. Follow their code on GitHub.

github.com

 

반응형
반응형

나는 항상 마이바티스를 통해서 페이징처리를 했다.

이떄 필요한게 mysql 같은겨우는 offset과 limit 

오라클은 rownum이 들어간다.

하지만 JPA를 해보니 쿼리문 없이

어느정도 페이징 처리가 가능했다. 

 

  살펴보자.

 

아래에 위치한 대로 페이징 처리가 된다. 

 

먼저 컨트롤러를 보자 

 

@GetMapping("/board/list")
    public String boardList(Model model,
                            @PageableDefault(page = 0, size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable,
                            String searchKeyword) {

        Page<Board> list = null;

        if(searchKeyword == null) {
            list = boardService.boardList(pageable);
        }else {
            list = boardService.boardSearchList(searchKeyword, pageable);
        }

        int nowPage = list.getPageable().getPageNumber() + 1;
        int startPage = Math.max(nowPage - 4, 1);
        int endPage = Math.min(nowPage + 5, list.getTotalPages());

        model.addAttribute("list", list);
        model.addAttribute("nowPage", nowPage);
        model.addAttribute("startPage", startPage);
        model.addAttribute("endPage", endPage);

        return "boardlist";
    
    }

이떄 가장 중요한것은 

@PageableDefault(page = 0, size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable

이부분이다.

page = 현재 페이지

size = 보여줄 게시물수 

sort = "페이징 조건"

direction = 오름정렬 등

 

이렇게 설정해준뒤 

 

nowPage , StartPage, endPage 변수를 각각 적용해준다. 

 

이제 서비스단으로 보자 .

 

 public Page<Board> boardList(Pageable pageable){
        return  boardRepository.findAll(pageable);
    }

 

findAll에 아까 추가한 pageable을 추가해준다. 

그뒤 JPA레포토리를 이용하여 리턴한다. 

 

타임리프를 이용하여

 

    <th:block th:each="page : ${#numbers.sequence(startPage, endPage)}">
          <a th:if="${page != nowPage}" th:href="@{/board/list(page = ${page - 1}, searchKeyword = ${param.searchKeyword})}" th:text="${page}"></a>
          <strong th:if="${page == nowPage}" th:text="${page}" style="color : red"></strong>
      </th:block>

th:each 반복문을 이용하여 페이지를 꺼내준다. 

그뒤 스트롱태그를 이용하여 현재 해당하는 페이지에 연결해준다. 

 

 

 

이런식으로 페이징처리를 하면된다. 

 

    select
        board0_.id as id1_0_,
        board0_.content as content2_0_,
        board0_.title as title3_0_ 
    from
        board board0_ 
    where
        board0_.title like ? escape ? 
    order by
        board0_.id desc limit ?,
        ?

콘솔창에 SQL문이 다음과 같이 나온다. 

 

 

https://github.com/MoonSeokHyun

 

MoonSeokHyun - Overview

http://mls0000.dothome.co.kr/. MoonSeokHyun has 14 repositories available. Follow their code on GitHub.

github.com

 

반응형
반응형

저번에는 수정하기를 해보았다.

이번에는 수정하면 수정했다.

글 등록되면 글록 되었다. 

 

등 

이런 alert 창을 띄워 보자

 

우선 message.html을 만들어 보자

 

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<script th:inline="javascript">

    /*<![CDATA[*/

    var message = [[${message}]];
    alert(message);

    location.replace([[${SearchUrl}]]);

    /*]]>*/
</script>

<body>

</body>
</html>

 

이런식으로 message를 만들었다. 

 

그다음 컨트롤러를 보자 

 

    @PostMapping("/board/update/{id}")
    public String boardUpdate(@PathVariable("id") Integer id , Board board , Model model){

        Board boardTemp = boardService.boardView(id);
        boardTemp.setTitle(board.getTitle());
        boardTemp.setContent(board.getContent());

        model.addAttribute("message" , "글 수정 완료.");
        model.addAttribute("SearchUrl" , "/board/list");

        // 절대 이렇게 하면 안되고 Jpa에서 제공하는 변경감지나 Merge 기능을 따로 공부하자.
        boardService.write(boardTemp);

        return "Message";
    }

 

우선 리턴값을 message로 하면 글 수정이 되었을때 메시지로 이동이 된다. 

 

즉 이 순서다

 

글 수정 > 메시지창 > 리스트 페이지

 

글 수정을 하면 먼저 수정이 되고 메시지.html로 가서

모델에서 받은 값들로 변경되어 

메시지를 출력한다. 

 

 

반응형

+ Recent posts