React
[React] redux를 이용하여 게시판 만들기(2) - 떽떽대는 개발공부
떽이
2021. 1. 26. 18:17
2021/01/25 - [React] - [React] redux 를 이용하여 게시판 만들기(1) - 떽떽대는 개발공부
오늘은 redux 를 이용하여 게시판 만들기를 이어서 포스팅 하도록 하자.
저번 글에서는 글 작성과 작성된 글을 list 에서 보여주는 부분을 구현했다.
이번 글에서는 작성된 글을 상세보기 페이지에서 확인할 수 있도록 해보자.
먼저 boardContent.js 를 간단히 작성한다.
src/components/BoardContent.js
import React from 'react';
function BoardContent() {
return(
<div>
<h2>상세보기</h2>
<div>
<div>
<input type='text' />
</div>
<div>
<textarea />
</div>
<div>
<button type='button'>edit</button>
<button type='button'>delete</button>
</div>
</div>
</div>
)
}
export default BoardContent;
이제, BoardList 에서 목록 클릭 시 해당 글로 이동할 수 있도록 BoardList에 코드를 추가 해준다.
src/components/BoardList.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Link } from 'react-router-dom';
import { selectRow } from '@modules/boardReducer'
function BoardList() {
const {inputData} = useSelector(state => state.boardReducer)
const {lastId} = useSelector(state => state.boardReducer)
// 클릭한 글의 id를 넘겨주기 위해 dispatch 를 사용한다.
const dispatch = useDispatch();
// reducer 의 selectRow 함수에 선택한 id값을 넘겨준다.
const selectContent = (id) => {
dispatch(selectRow(id))
}
return(
<div>
<h2>게시판</h2>
<div>
<table className='listTable'>
<tbody>
<tr>
<td className='listTableIndex th'>index</td>
<td className='listTableTitle th'>title</td>
</tr>
{lastId !== 0 ?
inputData.map(rowData => (
rowData.id !== '' &&
<tr>
// 해당 글을 클릭하면 Link to 로 컴포넌트가 이동되며, td에 onClick 이벤트를 추가하여 id 값을 전달한다.
// 이 때 id 값을 매개변수로 주기 위해 onClick 을 함수형으로 전달 하였다.
<td className='listTableIndex' onClick={() => selectContent(rowData.id)}>
<Link to='/BoardContent'>{rowData.id}</Link>
</td>
<td className='listTableTitle' onClick={() => selectContent(rowData.id)}>
<Link to='/BoardContent'>{rowData.title}</Link>
</td>
</tr>
)) :
<tr>
<td className='listTableIndex'></td>
<td className='listTableTitle noData'>작성된 글이 없습니다.</td>
</tr>
}
</tbody>
</table>
</div>
</div>
)
}
export default BoardList;
boardReducer.js 에서 전달 받은 id로 select 할 data를 뽑는다.
역시 순수함수로 작성되어야 하기 때문에 전달받을 data 를 담아줄 selectRowData 를 생성하였다.
src/modules/boardReducer.js
const _SAVE = 'DATA_SAVE';
const _SELECT = 'DATA_SELECT'
export const dataSave = (inputData) => ({
type: _SAVE,
inputData: {
id: inputData.id,
title: inputData.title,
content: inputData.content
}
})
// BoardContent.js 에서 id값을 매개변수로 받는다.
export const selectRow = (id) => ({
type: _SELECT,
inputData: {
id: id,
}
})
const initialState = {
lastId: 0,
inputData: [
{
id: '',
title: '',
content: ''
}
],
// select 된 data를 담아주기 위해 생성
selectRowData: {}
}
export default function boardReducer(state = initialState, action){
switch(action.type) {
case _SAVE:
return {
lastId: state.lastId + 1,
inputData: state.inputData.concat({
...action.inputData,
id: state.lastId + 1,
})
}
case _SELECT:
return {
...state,
// state 에 action 으로 전달받은 id값과 일치하는 data가 있다면 return 해준다.
selectRowData: state.inputData.find(row => row.id === action.inputData.id)
}
default:
return state
}
}
이제 BoardContent.js 에서 선택된 값을 state 에서 받아온다.
src/components/BoardContent.js
import React from 'react';
import { useSelector } from 'react-redux'
function BoardContent() {
const { selectRowData } = useSelector(state => state.boardReducer)
return(
<div>
<h2>상세보기</h2>
<div>
<div>
<input type='text' className='inputTitle' value={selectRowData.title} />
</div>
<div>
<textarea className='inputContent' value={selectRowData.content} />
</div>
<div>
<button type='button' className='editBtn'>edit</button>
<button type='button' className='deleteBtn'>delete</button>
</div>
</div>
</div>
)
}
export default BoardContent;
이렇게 하면 아래와 같이 목록 클릭 시 해당 글을 확인할 수 있다.