본격적인 리액트 공부를 하기 위해 구글링을 하다 아래의 블로그에서 게시판 만드는 것을 따라 해 보았다.
[ React ] 리액트 Redux 로 게시판 만들어보기
이번 포스팅에선 리덕스를 이용해 게시판의 기본적인 Create, Read, Update, Delete 구현을 다룬다. 공부하며 간단히 만들어본거라 설명이 미약한 점 참고해주시길. 먼저 프로젝트를 만들고 리덕
mjn5027.tistory.com
이해가 될듯 말듯 알쏭달쏭한 상태에서 router 를 이용하여 페이지 이동할 수 있는 기능을 추가 구현해 볼까 한다.
redux 관련 부분은 상기의 페이지에서 확인하면 될 것이다. 이번 글에서는 router 사용을 중점으로 했다.
내가 공부했던 Router 글은 아래와 같다.
2021/01/04 - [React] - [React] Router 를 사용하여 페이지 접근하기-떽떽대는 개발공부
[React] Router 를 사용하여 페이지 접근하기-떽떽대는 개발공부
Single Page Application(SPA) 서버로부터 새로운 페이지를 불러오지 않고 현재의 페이지에 컴포넌트를 통해 동적으로 다시 작성하여 클라이언트와 소통하는 웹 애플리케이션이다. 필요한 모든 소스는
ddeck.tistory.com
폴더 구조는 아래와 같이 구성하였다.

먼저 Router를 사용하기 위해 react-router-dom 를 install 한다.
$ npm i react-router-dom
설치가 완료 되었으면 App.js 에 BrowserRouter 를 추가하여 Container.js 를 감싸준다.
src/App.js
import React from 'react'; import Container from '@container/Container'; import { BrowserRouter } from 'react-router-dom'; function App() { return ( <div> <BrowserRouter> <Container /> </BrowserRouter> </div> ) } export default App;
이전 router 공부할 때엔 하나의 화면에서 구현을 했으므로 화면 안에서 <Router>로 감싸 주었으나, 이번엔 페이지 밖에서 묶어주었다.
src/container/Container.js
import React from 'react'; import {BrowserRouter as Route, Switch} from 'react-router-dom'; import BoardList from '@container/BoardList'; import BoardNew from '@container/BoardNew'; import BoardContent from '@container/BoardContent'; import HomeButton from '@components/HomeButton'; import WriteButton from '@components/WriteButton'; function Container() { return ( <div> <div> <Switch> <Route path='/' exact component={BoardList}/> <Route path='/BoardNew' exact component={BoardNew} /> <Route path='/BoardContent' component={BoardContent} /> </Switch> </div> <div> <HomeButton /> <WriteButton /> </div> </div> ); } export default Container;
먼저, container.js 는 위와 같이 구성되었다.
Switch 로 route 별로 나타낼 페이지 섹션을 주었고, 아래에는 home 버튼과 write 버튼을 추가하여 줄 것이다.
src/components/HomeButton.js
import React from 'react'; import { BrowserRouter as Link } from 'react-router-dom'; function HomeButton() { return ( <button> <Link to='/'> Home </Link> </button> ); } export default HomeButton;
src/components/WriteButton.js
import React from 'react'; import { BrowserRouter as Link } from 'react-router-dom'; function WriteButton() { return ( <button> <Link to='/BoardNew'> Write </Link> </button> ); } export default WriteButton;
간단하게 버튼 두개를 생성하였다.
버튼 클릭 시 router 를 이용하여 페이지를 이동하기 위해 Link 기능을 추가하였다.
Link 에서 지정한 path 로 페이지가 이동되면 Container.js 페이지에서 해당 component 를 불러와 페이지를 구현할 것이다.
먼저, 글 작성 페이지를 구현할텐데 글 작성 페이지에서 save 버튼을 클릭했을 때 함수 사용을 하기 위해 container.js 에서 먼저 함수를 작성해준다.
src/container/Container.js
import React, {useState} from 'react'; import BoardList from '@container/BoardList'; import BoardNew from '@container/BoardNew'; import BoardContent from '@container/BoardContent'; import { useDispatch, useSelector } from 'react-redux'; import { boardSave } from '@module/boardReducer'; import HomeButton from '@components/HomeButton'; import WriteButton from '@components/WriteButton'; import {BrowserRouter as Route, Switch} from 'react-router-dom'; function Container() { // State let [inputData, setInputData] = useState({ boardId: '', boardTitle: '', boardContent: '' }); const dispatch = useDispatch(); // 글 작성 페이지에서 onSave 를 호출하면 action 에 dispatch 됨 const onSave = (saveData) => dispatch(boardSave(saveData)); // 글 작성 페이지에서 input value 값이 변할 때마다 값 변경 const changeInput = (e) => { setInputData({ ...inputData, [e.target.name]: e.target.value }) } // 글 작성 페이지에서 save 버튼 클릭 시 input 란 reset const resetForm = () => { setInputData({ boardId: '', boardTitle: '', boardContent: '' }) } return ( <div> <div> <Switch> <Route path='/' exact component={BoardList}/> <Route path='/BoardNew' exact component={() => <BoardNew onSave={onSave} inputData={inputData} changeInput={changeInput} resetForm={resetForm} /> } /> <Route path='/BoardContent' component={BoardContent} /> </Switch> </div> <div> <HomeButton /> <WriteButton /> </div> </div> ); } export default Container;
글 작성 페이지에서 사용할 수 있도록 함수 3개와 InputData를 props 로 넘겨줄 것이다.
router 사용 시 props 값을 넘겨주기 위해서는 함수형으로 전달 해주어야만 props 값이 전달된다.
그렇지 않으면 전달되지 않아서 애먹을 것이다.
src/container/BrandNew.js
import React from 'react'; function BoardNew({ onSave, changeInput, inputData, resetForm }) { const saveBtnClick = (e) => { e.preventDefault(); onSave(inputData); resetForm(); } return ( <> <div width="50"> <form onSubmit={saveBtnClick}> <div> 제목 : <input type="text" name="boardTitle" onChange={changeInput} value={inputData.boardTitle} /> </div> <div> 내용 : <input type="text" name="boardContent" onChange={changeInput} value={inputData.boardContent} /> </div> <input type="hidden" name="boardId" onChange={changeInput} value={inputData.boardId} /> <button type="submit" >신규 게시글 저장</button> </form> </div> </> ) }; export default BoardNew;
container.js 에서 넘겨받은 props 값으로 글 작성 페이지를 만들어준다.
list 구현은 넘겨받는 props 값 없이 해당 페이지에서 구현할 것이다.
src/container/BoardList.js
import React from 'react'; import { BrowserRouter as Link } from 'react-router-dom'; import { boardRemove } from '@module/boardReducer'; import { useDispatch, useSelector } from 'react-redux'; function BoardList() { const dispatch = useDispatch(); // 삭제 버튼 클릭 시 action 에 dispatch 해줌 const onRemove = (boardId) => dispatch(boardRemove(boardId)); // 현재 store 에 있는 board field 를 구독 const {boards} = useSelector(state => state.boardReducer); return ( <div> <table border="1"> <tbody> <tr align="center"> <td width="50">번호</td> <td width="100">제목</td> <td width="200">내용</td> </tr> {boards.map(row =>( <tr> <td><Link to={`/BoardContent/${row.boardId}/${row.boardTitle}/${row.boardContent}`}>{row.boardId}</Link></td> <td><Link to={`/BoardContent/${row.boardId}/${row.boardTitle}/${row.boardContent}`}>{row.boardTitle}</Link></td> <td><Link to={`/BoardContent/${row.boardId}/${row.boardTitle}/${row.boardContent}`}>{row.boardContent}</Link></td> <td><button onClick={() => onRemove(row.boardId)}>삭제</button></td> </tr> ))} </tbody> </table> </div> ) } export default BoardList;
list 오른쪽에 삭제 버튼을 구현하기 위해 onRemove 함수를 사용하여 action 에 dispatch 해 주었다.
글 리스트에서 제목이나 내용을 클릭하면 content 페이지로 이동하기 위해 (get 방식을 사용할 것이다)
Link 를 사용하여 boardId, boardTitle, boardContent 를 url 에 추가하였다.
이제 글을 클릭했을 때 detail 을 보여주는 페이지를 작성한다.
src/container/BoardContent.js
import React from 'react'; function BoardContent() { const boardId_temp = decodeURI(window.location.href).split('http://localhost:3000/BoardContent/').reverse()[0]; const boardId = boardId_temp.split('/')[0]; const boardTitle_temp = decodeURI(window.location.href).split(`http://localhost:3000/BoardContent/${boardId}/`).reverse()[0]; const boardTitle = boardTitle_temp.split('/')[0]; const boardContent_temp = decodeURI(window.location.href).split(`http://localhost:3000/BoardContent/${boardId}/${boardTitle}/`).reverse()[0]; const boardContent = boardContent_temp.split('/')[0]; return ( <div> <table border="1"> <tbody> <tr align="center"> <td width="50">{boardId}</td> <td width="300">{boardTitle}</td> </tr> <tr> <td colspan="2" width="350">{boardContent}</td> </tr> </tbody> </table> </div> ) } export default BoardContent;
여기에서는 prop 값을 get 방식으로 받아왔기 때문에 url 을 split 해서 값을 저장하였다.
이렇게 하면 모든 페이지 구현이 완료 되었을 것이다.
뭔가 미흡한 부분이 있어서 router 사용으로 prop 값을 넘기고, 받는 부분에 대해서는 조금 더 공부 할 생각이다.
일단 오늘의 공부는 여기까지..
'React' 카테고리의 다른 글
[React] props 전달받기 예제 - 떽떽대는 개발공부 (0) | 2021.01.21 |
---|---|
[React] input 데이터 수정 - 떽떽대는 개발공부 (0) | 2021.01.20 |
[React] 절대경로를 사용하여 css 적용하기 - 떽떽대는 개발공부 (0) | 2021.01.15 |
[React] React webpack 을 이용하여 개발 환경 구성하기 - 떽떽대는 개발공부 (0) | 2021.01.14 |
[React] react-dom 과 css animation 을 이용하여 loading 중 아이콘 구현하기 - 떽떽대는 개발공부 (0) | 2021.01.12 |
댓글