2023. 7. 12. 00:10ㆍGithub 프로젝트/게시판프로젝트
Github 저장소 :https://github.com/BerkleyLim/project_board
GitHub - BerkleyLim/project_board: Spring Boot + React CRUD형 게시판 만들기 프로젝트 안내서
Spring Boot + React CRUD형 게시판 만들기 프로젝트 안내서. Contribute to BerkleyLim/project_board development by creating an account on GitHub.
github.com
개발 환경은
Front : React 기반
Back-End : Spring Boot 기반
DB : My-SQL 기반
Nodejs 및 npm 패키지 / java와 maven 이 미리 설치를 한 상태로 먼저 환경 설정을 셋팅을 한다.
이번 시간에는 immutablilty-helper 라는 불가변성 라이브러리를 사용하여 state 값 일부만 변동하고,
즉시 리액트 버전 crud 기능이 탑재된 코드를 구현해보겠습니다.
1) src/App.js에 immutablilty-helper 를 임포트 시키겠습니다.
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
2) 생성 및 수정용 Form을 준비합니다. src/modal/ModalComponent.jsx
이 코드의 의미는 수정 및 삽입의 대한 폼을 나타내는 코드입니다.
isModal : App.js의 state값에 모달 창 띄울지 파라미터
modalViewToggle : 모달 띄우는 이벤트
createBoard : 삽입 관련 메서드
message : 버튼에 추가 or 수정 텍스트 표시하는 파라미터
mode : 추가 모드 or 수정 모드 구분 짓는 파라미터 변수
updateData : 수정할려는 state 값
updateIndex : 수정할려는 state index 값
updateBoard :수정 할려는 메소드
import React, { useEffect, useState } from 'react'
import {
Card,
CardBody,
CardText,
Button,
Row,
Col,
Input,
Modal,
ModalHeader,
ModalBody,
FormGroup,
} from "reactstrap";
import update from "immutability-helper";
function ModalComponent({isModal, modalViewToggle, createBoard, message, mode, updateData, updateIndex, updateBoard}) {
const [inputCreate, setInputCreate] = useState();
const [inputUpdate, setInputUpdate] = useState({bno:updateData?.bno});
// 삽입용
const createOnChange = (e) => {
const { name, value } = e.target;
setInputCreate({
...inputCreate,
[name]: value,
});
};
// console.log(updateData)
// 수정용
const updateOnChange = (e) => {
const { name, value } = e.target;
setInputUpdate({
...inputUpdate,
bno:updateData?.bno,
[name]: value,
});
console.log(inputUpdate)
};
return (
<Modal
isOpen={isModal}
toggle={modalViewToggle}
centered={true}
fullscreen={true}
>
<ModalHeader toggle={modalViewToggle}>
{message + " 게시글을 입력하세요"}
</ModalHeader>
<ModalBody>
<Card className="my-2" color="primary" outline>
<CardBody>
<FormGroup>
<CardText>
제목
{
mode === "create" ?
<Input name="title" onChange={createOnChange}/>
:
<Input name="title" defaultValue={updateData?.title} onChange={updateOnChange}/>
}
내용
{
mode === "create"?
<Input type="textarea" name="contents" onChange={createOnChange} />
:
<Input type="textarea" name="contents" defaultValue={updateData?.contents} onChange={updateOnChange} />
}
</CardText>
</FormGroup>
<Row>
<Col sm={{ offset: 3, size: "auto" }}>
{
mode === "create"?
<Button
color="success"
onClick={() => {
createBoard(inputCreate);
}}
>
추가
</Button>
:
<Button
color="primary"
onClick={() => {
updateBoard(inputUpdate,updateIndex);
}}
>
수정
</Button>
}
</Col>
<Col sm={{ offset: 4, size: "auto" }}>
<Button
onClick={() => {
modalViewToggle()
}}
>
닫기
</Button>
</Col>
</Row>
</CardBody>
</Card>
</ModalBody>
</Modal>
)
}
export default ModalComponent
이 때, 입력 추가용 state와 수정용 state를 통해 게시판 형태로 사용 가능합니다.
src/App.js에서 Modal을 추가해줍니다.
import ModalComponent from "./modal/ModalComponent";
<ModalComponent
isModal={isModal}
modalViewToggle={modalViewToggle}
createBoard={createBoard}
message={message}
mode={mode}
updateData={updateData}
updateIndex={updateIndex}
updateBoard={updateBoard}
/>
3) 모달 띄우기 (src/App.js)
아래와 같이 함수를 지정하여 사용후 모달 관련 함수를 사용합니다.
모달의 대해 자세한 내용은 reactstrap 공식 문서를 참조 바랍니다.
https://reactstrap.github.io/?path=/docs/components-modal--modal
Storybook
reactstrap.github.io
// 모달 띄울것인지 아닌지 상태 변수를 가리킴
const [isModal, setIsModal] = useState(false);
// 모달 화면 띄우는 이벤트
const modalViewToggle = () => setIsModal(!isModal);
// 모드에 수정모드 or 삽입 모드 설정하는 모달창
const [mode, setMode] = useState("create");
// 모달에 버튼 기능 추가 or 수정 텍스트 표시할 변수
const [message, setMessage] = useState();
// 모달 이벤트를 변화 주는 메서드
const modalViewToggle = () => setIsModal(!isModal);
// state 값 변화시 각 state 변화된 결과를 렌더링 하기 위해 추가
// 특히 board state 값을 위한 메서드
const [isStateChange, setIsStateChange] = useState(false);
4) 생성 관련 기능 추가
// 모달에 전달해주는 메서드
const readyChange = () => {
setMessage("추가"); // 버튼 추가 텍스트 전달
setMode("create"); // 생성 모드로 모달 창 띄우기
modalViewToggle(); // 모달 띄우기
};
// 생성 메서드
// 이때, 불가변성으로 생성 할 수 있는 기능을 삽입한다.
const createBoard = (data) => {
// front 화면에서 생성하는 것처럼 행동
setBoard(
update(board, {
$push: [data],
})
);
modalViewToggle(); // 모달창을 닫는다.
};
5) 수정 관련 기능 추가
// 수정용 state 값 : data - 해당 index의 데이터 전달, index - 해당 인덱스 전달
const [updateData, setUpdateData] = useState();
const [updateIndex, setUpdateIndex] = useState();
// 모달에 전달해주는 값 메소드 추가
const readyUpdate = (data, index) => {
setMessage("수정"); // 버튼에 수정 표시
setMode("update"); // 수정 모드로 모달 열기
modalViewToggle(); // 모달 열기
setUpdateData(data); // 수정 모드 해당 데이터 전달
setUpdateIndex(index); // 수정 모드 해당 인덱스 전달
};
// 수정 이벤트
const updateBoard = (data, index) => {
// 불가변성으로 이용하여 해당 데이터 수정
setBoard(
update(board, {
$merge: { [index]: data },
})
);
modalViewToggle(); // 모달 창 닫기
setIsStateChange(!isStateChange); // state 값 변하면 바로 리렌더링하는 기능
};
6) 삭제를 위한 기능
// 삭제를 위한 메서드
const deleteBoard = (index) => {
const deleteData = board[index];
setBoard(
update(board, {
$splice: [[index, 1]],
})
);
};
7) 기능 추가 후, rendering 하는 코드에 아래와 같이 수정합니다.
{board?.map((b, index) => (
<Card key={index} className="my-2" color="primary" outline>
<CardHeader>{b?.title}</CardHeader>
<CardBody>
<CardText>{b?.contents}</CardText>
<br />
<br />
<Row>
<Col sm={{ offset: 3, size: "auto" }}>
<Button
color="primary"
onClick={() => {
readyUpdate(b, index);
}}
>
수정
</Button>
</Col>
<Col sm={{ offset: 4, size: "auto" }}>
<Button color="danger" onClick={() => deleteBoard(index)}>
삭제
</Button>
</Col>
</Row>
</CardBody>
</Card>
))}
<br />
<br />
<br />
<br />
<Row>
<Button
color="success"
onClick={() => {
readyChange();
}}
>
추가
</Button>
</Row>
8) src/App.js 전체 코드
import {
Card,
CardHeader,
CardBody,
CardText,
Button,
Row,
Col,
} from "reactstrap";
import "./App.css";
import { useEffect, useState } from "react";
import ModalComponent from "./modal/ModalComponent";
import update from "immutability-helper";
function App() {
const data = [
{
bno: 1,
title: "제목1",
contents: "내용1",
},
{
bno: 2,
title: "제목2",
contents: "내용2",
},
{
bno: 3,
title: "제목3",
contents: "내용3",
},
{
bno: 4,
title: "제목4",
contents: "내용4",
},
];
// console.log(data);
// 게시판 데이터 담는 state 값
const [board, setBoard] = useState();
// 모달창띄울지 여부 확인
const [isModal, setIsModal] = useState(false);
// 모달에 수정모드 or 삽입모드 결정 짓는 state 값
const [mode, setMode] = useState("create");
// 버튼 텍스트 전달할 state값
const [message, setMessage] = useState();
// 수정용 state 값 : data - 해당 index의 데이터 전달, index - 해당 인덱스 전달
const [updateData, setUpdateData] = useState();
const [updateIndex, setUpdateIndex] = useState();
// state 값 변화시 각 state 변화된 결과를 렌더링 하기 위해 추가
// 특히 board state 값을 위한 메서드
const [isStateChange, setIsStateChange] = useState(false);
// 모달 여/닫기 이벤트용 메서드
const modalViewToggle = () => setIsModal(!isModal);
// html 렌더링 후 데이터 가져오기를 위한 기능
// [] 는 첫번째만 호출
useEffect(() => {
setBoard(data);
}, []);
console.log(board);
// 모달에 전달해주는 삽입 메서드
const readyChange = () => {
setMessage("추가"); // 버튼 추가 텍스트 전달
setMode("create"); // 생성 모드로 모달 창 띄우기
modalViewToggle(); // 모달 띄우기
};
// 생성 메서드
// 이때, 불가변성으로 생성 할 수 있는 기능을 삽입한다.
const createBoard = (data) => {
// front 화면에서 생성하는 것처럼 행동
setBoard(
update(board, {
$push: [data],
})
);
modalViewToggle(); // 모달창을 닫는다.
};
// 모달에 전달해주는 데이터 수정 메소드 추가
const readyUpdate = (data, index) => {
setMessage("수정"); // 버튼에 수정 표시
setMode("update"); // 수정 모드로 모달 열기
modalViewToggle(); // 모달 열기
setUpdateData(data); // 수정 모드 해당 데이터 전달
setUpdateIndex(index); // 수정 모드 해당 인덱스 전달
};
// 수정 이벤트
const updateBoard = (data, index) => {
// 불가변성으로 이용하여 해당 데이터 수정
setBoard(
update(board, {
$merge: { [index]: data },
})
);
modalViewToggle(); // 모달 창 닫기
setIsStateChange(!isStateChange); // state 값 변하면 바로 리렌더링하는 기능
};
// 삭제를 위한 메서드
const deleteBoard = (index) => {
setBoard(
update(board, {
$splice: [[index, 1]],
})
);
};
return (
<div className="container">
<h1>게시판 프로젝트</h1>
<br />
<br />
<br />
<br />
{board?.map((b, index) => (
<Card key={index} className="my-2" color="primary" outline>
<CardHeader>{b?.title}</CardHeader>
<CardBody>
<CardText>{b?.contents}</CardText>
<br />
<br />
<Row>
<Col sm={{ offset: 3, size: "auto" }}>
<Button
color="primary"
onClick={() => {
readyUpdate(b, index);
}}
>
수정
</Button>
</Col>
<Col sm={{ offset: 4, size: "auto" }}>
<Button color="danger" onClick={() => deleteBoard(index)}>
삭제
</Button>
</Col>
</Row>
</CardBody>
</Card>
))}
<br />
<br />
<br />
<br />
<Row>
<Button
color="success"
onClick={() => {
readyChange();
}}
>
추가
</Button>
</Row>
<ModalComponent
isModal={isModal}
modalViewToggle={modalViewToggle}
createBoard={createBoard}
message={message}
mode={mode}
updateData={updateData}
updateIndex={updateIndex}
updateBoard={updateBoard}
/>
</div>
);
}
export default App;
마치며,
지금까지 React로 이용하여 CRUD 까지 구현해보았습니다.
다음 시간에는 API를 이용하여 데이터 CRUD 구성하기 위해 DB 설계와 SQL문, 그리고 Spring Boot API를 이용하여 인터페이스 호출까지 하는 시간을 가지겠습니다.
'Github 프로젝트 > 게시판프로젝트' 카테고리의 다른 글
[6] CRUD 게시판 프로젝트 - Maven 버전 Spring Boot 설치 및 My-Batis 셋팅 (0) | 2023.07.12 |
---|---|
[5] CRUD 게시판 프로젝트 - SQL문 CRUD 설계 (0) | 2023.07.12 |
[4] CRUD 게시판 프로젝트 - DBeaver로 DB 생성과 Table 및 Filed 생성 (0) | 2023.07.12 |
[2] CRUD 게시판 프로젝트 - React UI 구성 (0) | 2023.07.11 |
[1] CRUD 게시판 프로젝트 - React 셋팅 (0) | 2023.07.11 |