중앙정보기술인재개발원/React

[React] 게시판 만들기_1

soidev 2025. 7. 17. 10:12

backend : spring

frontend : react

 

package.json > dependencies  : 18.3.1버전

스프링에서 build.gradle이거랑 똑같은 파일이라고 생각하면됨

package-lock.json react를 의존하는 라이브러리를 연쇄적으로 설치함

 

npm install

npm install react-router-dom

npm install axios

npm run dev

 

public,src,index.html,package.json 만 들고가면 됨 깃이나 다른데서 이 소스를 하고싶을때

public 쪽은 기본 이미지 들어감. spring에서 static에있던것들을 여기선 public에다가 넣음

 

src > jsx,component,service

 

페이지별로 폴더를만들고

얘에 있는 공용을 만들기??

 

파일구조는 파일마다 컴포넌트 하기 이런식으로

 

링크. : 액터/기능/페이지 user/board/loginPage

 

라우터는 언제든지 할 수 있는거?!?

 

import { useState } from "react";
import BottomNavigation from "../../commons/component/Bottomnavigation";

export default function RegisterPage() {

    //상태변수를 만든다.
    const [accountName,setAccountName] = useState('123123');

    return (
        <>
            <div className="container-fluid">
                <div className="row">
                    <div className="col">
                        회원 가입<br/>
                        아이디: <input value={accountName} type="text" placeholder="아이디" /><br/>
                        비번: <input type="password" placeholder="비번" /><br/>
                        닉넴: <input type="text" placeholder="닉네임" /><br/>
                        성별 : <input type="radio" name="gender" />남
                        <input type="radio" name="gender" />여<br/>
                        생일: <input type="date" placeholder="생년월일" /><br/>
                        이메일: <input type="text" placeholder="이메일" /><br/>
                        폰넘버: <input type="text" placeholder="폰넘버" /><br/>
                        <button className="btn btn-primary">회원 가입</button>
                    </div>
                </div>
            </div>

            <BottomNavigation />
        </>
    );
}

 

글자를 쓸 때마다 onchange가 발생함 그래서 

123123 부분에 안 고쳐지고 안 바뀐다.

const handleAccountNameChange = (e) => {
        setAccountName(e.target.value);
    };
    
    .....
    
    
 아이디: <input onChange={handleAccountNameChange} value={accountName} type="text" placeholder="아이디" /><br/>

이런식으로 이벤트를 가져오면 123123부분이 수정되면서 알아서 랜더링 된다!

 

하지만 지금 input이 10개 정도 있는데 state랑 eventhandle를 10개씩 만들기는 너무 귀찮고 하니 다른 방법

 

import { useState } from "react";
import BottomNavigation from "../../commons/component/Bottomnavigation";
import axios from "axios";
import { useNavigate } from "react-router-dom";

export default function RegisterPage() {
    
    //state입력양식에 엮는것 젤 중요함
    const [formData, setFormData] = useState({
        accountName: '',
        password: '',
        nickname: '',
        email: '',
        gender: '',
        birth: '',
        phone: ''
    });

    // console.log(formData);
    
    const handleChange = (e) => {
        //굉장히 중요한 문법
        //변수선언해서 바로 값을 넘어주는 문법
        //구조분해문법
        //type,checked는 체크박스용임 그냥 쓰샤!
        const { name, value,type,checked } = e.target;
        
        const newValue = type === 'checkbox' ? checked : value;     //체크 박스 없어도 이거 써도 작동되나요? 네 됩니당 그냥 쓰세요 달력도 value임
        // 체크 박스일땐 value가 true false로 넘어옴 하지만 지금 라디오 버튼이라 value가 문자로 넘어옴


        //... : 원래값을 그대로 쓰겠다는 것
        //name은 accountName, value는 입력한 값
        //setFormData는 상태변수의 setter함수
        //formData는 상태변수의 현재값
        //이렇게 하면 formData의 값이 바뀌면서 랜더링이 다시 이루어지면서 화면에 입력한 값이 보임 이렇게 하면 상태변수의 값을 바꿀 수 있다.
        setFormData({
            ...formData,
            [name]: value
        });
    }

    //post같은 거 쓸 땐  axios이런거 쓸 때 async() 활용
    const navigate = useNavigate(); //href 하면 웹브라우저가 request해서 웹브라우저가 깜박임 근ㄷ게 react에선 무조건 깜박임 안됨 그래서 navi로 활용

    const handleSubmit = async()=>{
        //http://localhost:8080/api/user/register post로 axios로 전송
        const response = await axios.post('http://localhost:8080/api/user/register',formData);
        //.data =json

        //  여러 예외 처리 해야될 수 도 있음.

        alert("회원가입이 완료 되었습니다.");   //이거말고 다른 디자인으로 활용 가능

        //성공시 로그인 페이지로 이동
        navigate('/user/board/login');
    }


    return (
        <>
            <div className="container-fluid">
                <div className="row">
                    <div className="col">
                        회원 가입<br/>
                        아이디: <input onChange={handleChange} name="accountName" value={formData.accountName} type="text" placeholder="아이디" /><br/>
                        비번: <input onChange={handleChange} name="password" value={formData.password} type="password" placeholder="비번" /><br/>
                        닉넴: <input onChange={handleChange} name="nickname" value={formData.nickname} type="text" placeholder="닉네임" /><br/>
                        {/* 처음부터 초기값을 주면 된다??? */}
                        성별 : <input onChange={handleChange} name="gender" checked={formData.gender=='M'} value='M'  type="radio" />남
                        <input onChange={handleChange} name="gender" checked={formData.gender=='F'} value='F' type="radio" />여<br/>
                        생일: <input onChange={handleChange} name="birth" value={formData.birth} type="date" placeholder="생년월일" /><br/>
                        이메일: <input onChange={handleChange} name="email" value={formData.email} type="text" placeholder="이메일" /><br/>
                        폰넘버: <input onChange={handleChange} name="phone" value={formData.phone} type="text" placeholder="폰넘버" /><br/>
                        <button onClick={handleSubmit} className="btn btn-primary">회원 가입</button>
                    </div>
                </div>
            </div>

            <BottomNavigation />
        </>
    );
}

 

axios : Axios는 브라우저, Node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리이다.

  • 운영 환경에 따라 브라우저의 XMLHttpRequest 객체 또는 Node.js의 HTTP API 사용
  • Promise(ES6) API 사용
  • 요청과 응답 데이터의 변형
  • HTTP 요청 취소 및 요청과 응답을 JSON 형태로 자동 변경

# HTTP Methods

클라이언트가 웹서버에게 사용자 요청의 목적/종류를 알리는 수단

이 Method중 Axios 통신하면서 가장 많이 사용되는 메소드를 정리해보았다.

1. GET

GET : 입력한 url에 존재하는 자원에 요청을 한다.

문법

axios.get(url,[,config])

Q) Get이 데이터를 받아오는 것이라고 했는데, 저는 로그인을 구현할때 GET을 사용했는데요?

GET으로 로그인을 구현했을때 웹 사이트 주소창의 형태를 잘 보면 이러한 형태가 나온다.

www.server.com/login?accountName=t0001&pw=1111  // 실제로 없는 사이트

웹 사이트 뒤에 쿼리스트링이 붙여진 것을 확인할 수 있다.

 

✅ GET은 서버에서 어떤 데이터를 가져와서 보여준다거나 하는 용도이다.

2. POST

POST : 새로운 리소스를 생성(create)할 때 사용한다.

문법

axios.post("url주소",{
  data객체
    },[,config])

POST 메서드의 두 번째 인자는 본문으로 보낼 데이터를 설정한 객체 리터럴을 전달한다.

Q) Post는 새로운 리소스를 생성할 때 사용되는데 그러면 언제 POST를 사용하나요?

 

✅ 로그인, 회원가입 등 사용자가 생성한 파일을 서버에다가 업로드할때 사용한다.

 

3. Delete

REST 기반 API 프로그램에서 데이터베이스에 저장되어 있는 내용을 삭제하는 목적으로 사용한다.

문법

axios.delete(url,[,config]);

✅ Delete메서드는 HTML Form 태그에서 기본적으로 지원하는 HTTP 메서드가 아니다.

Delete메서드는 서버에 있는 데이터베이스의 내용을 삭제하는 것을 주 목적으로 하기에 두 번째 인자를 아예 전달하지 않는다.

 

4. PUT

REST 기반 API 프로그램에서 데이터베이스에 저장되어 있는 내용을 갱신하는 목적으로 사용된다.

문법

axios.put(url[, data[, config]])

✅ PUT메서드는 HTML Form 태그에서 기본적으로 지원하는 HTTP 메서드가 아니다.

PUT메서드는 서버에 있는 데이터베이스의 내용을 변경하는 것을 주 목적으로 하고 있다.

 

 

이제 이 회원가입 프론트앤드 코드를 마무리하면 백엔드로 보내야하니까 axios로 보냈지만

cors 오류가 떴음  이유가 뭐냐 백엔드는 8080 프론트는 5173 서로 서버 주소가 다르니까 백쪽에서 코드를 건드려야함

@Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("http://localhost:5173")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS","PATCH")
            .allowedHeaders("*")
            .allowCredentials(true);
    }

이 포트번호에서 날라오는 ajax는 허용해주겠다

원래는 따로 webconfig.java 따로따로 해야하는데 나는 지금 security  거기다 통합해서 overide 해줌

아래 강사님 코드처럼 여기 하나에다가 하는게 더 좋음 코드상