본문 바로가기
웹 프로그래밍/React

React & Spring Boot 웹게시판 만들기(블로그 튜토리얼 따라하기)-React

by 청량리 물냉면 2022. 1. 29.
반응형

따라할 튜토리얼 블로그

https://tinyurl.com/y8fx2afk

 

[리액트, 스프링부트 연동하여 CRUD 구현] #1 - 구상 (1/10)

리액트, 스프링부트 연동하여 CURD 구현하기 #1 구상 이 튜토리얼에서 리액트(React Js)와 스프링부트(Spring-boot)를 연동하여 간단한 CRUD를 구현하고자 합니다. 스프링부트를 사용하면서 타임리프나

corini.tistory.com

 


 

UserListComponent.jsx

import React, { Component } from "react";
import ApiService from "../../ApiService";

class UserListComponent extends Component {
  //constructor: 맨 처음 생성될 때 한번만 호출.
  //상태(state or 객체 변수)를 선언할 때 사용
  //초기 this.state 지정
  constructor(props) {
    super(props); //프로퍼티, 생명 주기 상태 초기화

    this.state = {
      users: [],
      message: null,
    };
  }

  //render() 함수가 jsx를 화면에 그린 이후 호출되는 함수.
  //컴포넌트가 화면에 모두 표현된 이후 해야 하는 작업들을 여기서 진행시킨다.
  componentDidMount() {
    this.reloadUserList();
  }

  //db에서 user 데이터 정보를 불러온다
  reloadUserList = () => {
    ApiService.fetchUsers()
      .then((res) => {
        //res: 매개변수
        this.setState({ users: res.data }); //then: 이행
      })
      .catch((err) => {
        console.log("reloadUserList() Error!", err); //예외 처리
      });
  };

  deleteUser = (userID) => {
    ApiService.deleteUser(userID)
      .then((res) => {
        //api 통신을 사용해 db에서 해당 유저 삭제
        this.setState({
          message: "User Deleted Successfully.",
        });
        this.setState({
          users: this.state.users.filter((user) => user.id !== userID),
          //삭제한 유저를 제외한 배열 생성
        });
      })
      .catch((err) => {
        console.log("deleteUser() Error!", err);
      });
  };

  //파라미터로 넘어온 user.id 값을 localStorage에 저장하고 "/edit-user"로 이동
  editUser = (ID) => {
    //로컬스토리지를 사용해 해당 유저 id를 일시적으로 저장
    window.localStorage.setItem("userID", ID);
    //route에서 "/edit-user" url로 이동하면 EditUserComponent.jsx를 보여준다
    this.props.history.push("/edit-user");
  };

  addUser = () => {
    window.localStorage.removeItem("userID");
    this.props.history.push("/add-user");
  };

  render() {
    return (
      <div>
        <h2>User List</h2>
        <button onClick={this.addUser}> Add User </button>
        <table>
          <thead>
            <tr>
              <th>ID</th>
              <th>FistName</th>
              <th>LastName</th>
              <th>UserName</th>
              <th>Age</th>
              <th>Salary</th>
            </tr>
          </thead>
          <tbody>
            {this.state.users.map((user) => (
              <tr key={user.id}>
                <td>{user.firstName}</td>
                <td>{user.lastName}</td>
                <td>{user.username}</td>
                <td>{user.age}</td>
                <td>{user.salary}</td>
                <td>
                  {/*user.id값을 파라미터로 넘겨 editUser 실행 */}
                  <button onClick={() => this.editUser(user.id)}>Edit</button>
                  <button onClick={() => this.deleteUser(user.id)}>
                    Delete
                  </button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  }
}

export default UserListComponent;

 

AddUserComponent.jsx

import React, { Component } from "react";
import ApiService from "../../ApiService";

class AddUserComponent extends Component {
  constructor(props) {
    super(props);

    this.state = {
      username: "",
      password: "",
      firstName: "",
      lastName: "",
      age: "",
      salary: "",
      massage: null,
    };
  }

  onChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value,
    });
  };

  saveUser = (e) => {
    e.preventDefault(); //브라우저 고유의 동작(이 경우 onClick)을 중단시켜주는 역할

    let user = {
      username: this.state.username,
      password: this.state.password,
      firstName: this.state.firstName,
      lastName: this.state.lastName,
      age: this.state.age,
      salary: this.state.salary,
    };

    ApiService.addUser(user)
      .then((res) => {
        this.setState({
          message: user.username + "님이 성공적으로 등록되었습니다.",
        });
        console.log(this.state.message);
        this.props.history.push("/users");
      })
      .catch((err) => {
        console.log("saveUser() 에러", err);
      });
  };

  render() {
    return (
      <div>
        <h2>Add User</h2>
        <form>
          <div>
            <label>User Name:</label>
            <input
              type="text"
              placeholder="please input your username"
              name="username"
              value={this.state.username}
              onChange={this.onChange}
            />
          </div>

          <div>
            <label>Password:</label>
            <input
              type="password"
              placeholder="please input your password"
              name="password"
              value={this.state.password}
              onChange={this.onChange}
            />
          </div>

          <div>
            <label>First Name:</label>
            <input
              placeholder="please input your first name"
              name="firstName"
              value={this.state.firstName}
              onChange={this.onChange}
            />
          </div>

          <div>
            <label>Last Name:</label>
            <input
              placeholder="please input your last name"
              name="lastName"
              value={this.state.lastName}
              onChange={this.onChange}
            />
          </div>

          <div>
            <label>Age:</label>
            <input
              type="number"
              placeholder="please input your age"
              name="age"
              value={this.state.age}
              onChange={this.onChange}
            />
          </div>

          <div>
            <label>Salary:</label>
            <input
              type="number"
              placeholder="please input your salary"
              name="salary"
              value={this.state.salary}
              onChange={this.onChange}
            />
          </div>

          <button onClick={this.saveUser}>Save</button>
        </form>
      </div>
    );
  }
}

export default AddUserComponent;

 

EditUserComponent.jsx

import React, { Component } from "react";
import ApiService from "../../ApiService";

/*
수정 메커니즘
1. localStorage를 통해 저장한 "userID"값으로 API통신
2. 해당 유저 정보를 DB에서 찾아 불러옴
3. setState를 통해 정보를 재작성(수정)
4. API통신을 통해 수정된 정보를 DB에 저장
*/
class EditUserComponent extends Component {
  constructor(props) {
    super(props);

    this.state = {
      username: "",
      password: "",
      firstName: "",
      lastName: "",
      age: "",
      salary: "",
      massage: null,
    };
  }

  componentDidMount() {
    this.loadUser();
  }

  //localStorage를 통해 저장한 "userID"값으로 API통신
  //해당 유저 정보를 DB에서 찾아 불러옴
  loadUser = () => {
    ApiService.fetchUserByID(window.localStorage.getItem("userID"))
      .then((res) => {
        let user = res.data;
        this.setState({
          id: user.id,
          username: user.username,
          firstName: user.firstName,
          lastName: user.lastName,
          age: user.age,
          salary: user.salary,
        });
      })
      .catch((err) => {
        console.log("loadUser() Error!", err);
      });
  };

  saveUser = (e) => {
    e.preventDefault();

    let user = {
      id: this.state.id,
      password: this.state.password,
      firstName: this.state.firstName,
      lastName: this.state.lastName,
      age: this.state.age,
      salary: this.state.salary,
    };

    ApiService.addUser(user)
      .then((res) => {
        this.setState({
          message: user.username + "님의 정보가 수정되었습니다.",
        });
        this.props.history.push("/users");
      })
      .catch((err) => {
        console.log("saveUser() 에러", err);
      });
  };

  render() {
    return (
      <div>
        <h2>Add User</h2>
        <form>
          <div>
            <label>User Name:</label>
            <input
              type="text"
              placeholder="please input your username"
              name="username"
              value={this.state.username}
              onChange={this.onChange}
            />
          </div>

          <div>
            <label>Password:</label>
            <input
              type="text"
              placeholder="please input your password"
              name="password"
              value={this.state.password}
              onChange={this.onChange}
            />
          </div>

          <div>
            <label>First Name:</label>
            <input
              type="text"
              placeholder="please input your first name"
              name="firstName"
              value={this.state.firstName}
              onChange={this.onChange}
            />
          </div>

          <div>
            <label>Last Name:</label>
            <input
              type="text"
              placeholder="please input your last name"
              name="lastName"
              value={this.state.lastName}
              onChange={this.onChange}
            />
          </div>

          <div>
            <label>Age:</label>
            <input
              type="text"
              placeholder="please input your age"
              name="age"
              value={this.state.age}
              onChange={this.onChange}
            />
          </div>

          <div>
            <label>Salary:</label>
            <input
              type="text"
              placeholder="please input your salary"
              name="salary"
              value={this.state.salary}
              onChange={this.onChange}
            />
          </div>

          <button onClick={this.saveUser}>Save</button>
        </form>
      </div>
    );
  }
}

export default EditUserComponent;

 

라우팅

컴포넌트에 주소를 부여해 해당 주소로 접속하면 해당 컴포넌트를 보여주도록 설정

첫번째 방법. App.js 내부에 작성

두번째 방법. 라우트 컴포넌트를 작성해 관리 (컴포넌트화) ✅

☞ 두번째 방법 사용

 

절차

  1. Axios로 Service 생성, RouterComponent.jsx 파일 작성
  2. App.js에 라우터 컴포넌트 포함시키기
  3. ApiService 파일이 작성되지 않았기 때문에 프로그램 실행은 되지 않음

 

React v5 → v6 변경사항

  • Switch → Routes로 변경
  • component → element로 변경

 

RouterComponent.jsx

import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import UserListComponent from "../user/UserListComponent";
import AddUserComponent from "../user/AddUserComponent";
import EditUserComponent from "../user/EditUserComponent";

const AppRouter = () => {
  return (
    <div>
      <BrowserRouter>
        <div style={style}>
          <Routes>
            <Route path="/" element={<UserListComponent />} />
            <Route path="/users" element={<UserListComponent />} />
            <Route path="/add-user" element={<AddUserComponent />} />
            <Route path="/edit-user" element={<EditUserComponent />} />
          </Routes>
        </div>
      </BrowserRouter>
    </div>
  );
};

const style = {
  color: "red",
  margin: "10px",
};

export default AppRouter;

 

Material UI 적용 생략

https://tinyurl.com/ydh9gu6b

 

[리액트, 스프링부트 연동하여 CRUD 구현] #7 - 리액트 앱에 Material UI 적용하기 (7/10)

리액트, 스프링부트 연동하여 CRUD 구현 #7 리액트 앱에 Material UI 적용하기 React Material UI는 리액트 앱을 빠르고 쉽게 디자인할 수 있는 프레임워크입니다. 자세한 내용은 공식 홈페이지를 참고하

corini.tistory.com

 

NavBar.jsx

import React from "react";

import {
  Button,
  Typography,
  AppBar,
  Toolbar,
  IconButton,
} from "@material-ui/core";
import { MenuIcon } from "@material-ui/icons";

const NavBar = () => {
  return (
    <div>
      <AppBar position="static">
        <Toolbar>
          <IconButton edge="start" color="inherit" aria-label="Menu">
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" style={style}>
            React User Application
          </Typography>
          <Button color="inherit">Login</Button>
        </Toolbar>
      </AppBar>
    </div>
  );
};

const style = {
  flexGrow: 1,
};

export default NavBar;

 

App.js

import { Container } from "@material-ui/core";
import React from "react";
import NavBar from "./component/route/NavBar";
import AppRouter from "./component/route/RouterComponent";

function App() {
  return (
    <div>
      <NavBar />
      <Container>
        <AppRouter />
      </Container>
    </div>
  );
}

export default App;

 

반응형