본격적인 리액트 공부를 하기 위해 구글링을 하다 아래의 블로그에서 게시판 만드는 것을 따라 해 보았다.
이해가 될듯 말듯 알쏭달쏭한 상태에서 router 를 이용하여 페이지 이동할 수 있는 기능을 추가 구현해 볼까 한다.
redux 관련 부분은 상기의 페이지에서 확인하면 될 것이다. 이번 글에서는 router 사용을 중점으로 했다.
내가 공부했던 Router 글은 아래와 같다.
2021/01/04 - [React] - [React] Router 를 사용하여 페이지 접근하기-떽떽대는 개발공부
폴더 구조는 아래와 같이 구성하였다.
먼저 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 |
댓글