PART6:Simply build App with Redux - Create / Redux Second Action
Create Implementation
지난 포스팅에서 폼을 대상으로 smart / dumb 컴포넌트를 분리 했었다.
오늘은 게시글 추가(Create) 기능을 구현 할것인데 컴포넌트의 흐름과
게시글 리스트 호출외에 다른 action 에 따른 redux 의 흐름을 경험
해볼수 있을것 같다.
게시글을 새로 생성 하려면 먼저 무엇을 해야할까.?
우선 사용자가 입력한 폼에 있는 값을 가져와야 한다.
smart component 인 ManageBoard.js
파일 부터 수정하자.
계획은 이렇다.
intput[type="text"]
가 onChange
될때 마다 새로운 state 값을 set 할것이다.
클래스 내부에서 호출할 props.contents 에 초기 객체를 설정해준다.
function mapStateToProps(state, ownProps) {
let initContent = {
id: '',
title:'',
content: '',
author:'',
date:''
}
return {
contents : initContent
}
}
생성자에 props.contents
를 호출해서 Object.assign
을 통해
immutable 한 객체를 state 초기값으로 설정해준다.
constructor(props, context) {
super(props, context);
this.state = {
contents: Object.assign({}, props.contents)
}
}
onChange
에서 사용할 updateChangeState
함수를 구현 한다.
updateChangeState(event) {
const field = event.target.name;
let contents = this.state.contents;
contents[field] = event.target.value;
return this.setState({contents: contents});
}
save
버튼이 눌렸을때 사용할 callWrite
함수를 구현 한다.
callWrite(event) {
event.preventDefault();
console.log(this.state.contents);
}
render() 에 있는 BoardForm
에 dumb Component 로 내려줄 props 를 정의 한다.
render() {
return (
<BoardForm
onChange={this.updateChangeState.bind(this)}
onSave={this.callWrite.bind(this)} />
);
}
smart component 에서 props 를 내려줬으니 이제 dumb component 를 수정 해야 한다.
BoardForm.js
파일을 열자.
onChange 와 onSave 를 파라미터로 추가해서 FormInput 태그와 textarea 그리고 submit에
추가하고 propTypes 를 함수로 정의해준다.
const BoardForm = ({onChange, onSave}) => {
return (
<form>
<h1>Write</h1>
<FormInput name="author" label="Author" onChange={onChange} />
<FormInput name="title" label="Title" onChange={onChange} />
<div className="form-group">
<label htmlFor="content">Content</label>
<textarea name="content" id="content" className="form-control"
onChange={onChange} ></textarea>
</div>
<input
type="submit"
value="Save"
className="btn btn-primary"
onClick={onSave}
/>
</form>
);
}
BoardForm.propTypes = {
onChange: PropTypes.func.isRequired,
onSave : PropTypes.func.isRequired
}
BoardForm 에 하위로 FormInput
이 있으니 해당 컴포넌트도 수정해준다.
FormInput.js
파일을 열자
const FormInput = ({name, label, onChange}) => {
return (
<div className="form-group">
<label htmlFor={name}>{label}</label>
<input type="text"
name={name}
className="form-control" onChange={onChange} />
</div>
);
}
FormInput.propTypes = {
name : PropTypes.string,
label: PropTypes.string,
onChange: PropTypes.func.isRequired
};
여기 까지 구현 했다면 다음과 같이 입력후 Save 를 클릭했을때
콘솔에서 폼값을 호출 하고 있는것을 확인 해볼수 있다.
이제 폼값을 가져 왔으니 폼값을 저장하는 일만 남았다.
액션 부터 생성하자.
actions 폴더에 actionTypes.js
에 상수를 추가 한다.
export const CALL_WRITE = 'CALL_WRITE';
api 폴더에 boardApi.js
에 saveContent
함수를 추가 한다.
static saveContent(content) {
content = Object.assign({}, content);
return new Promise((resolve, reject) => {
const minLength = 1;
content.id = parseInt(contents[contents.length - 1].id) + 1
content.date = new Date().toLocaleDateString().replace(/(\s*)/g,"").split('.').slice(0,3).join('/');
contents.push(content);
resolve(content);
});
}
id 와 date 를 생성해서 contents 배열에 push 했다.
이제 boardActions.js
파일로 이동 하자.
상단부에 actionTypes.js 에서 선언했던 CALL_WRITE
를 추가 하고
writeBoard
함수를 추가 한다.
export function writeBoard(content) {
return (dispatch) => {
return boardApi.saveContent(content)
.then(content => dispatch({type : CALL_WRITE, content }))
.catch(error => {
throw(error);
});
}
}
다음은 흐름에 따라 reducers 폴더에 있는 boardReducer.js
로 이동 한다.
상단에 CALL_WRITE
를 추가하고 switch 문에 Action 을 추가 한다.
case CALL_WRITE :
return [
...state,
Object.assign({}, action.content)
];
여기 까지 왔다면 redux 의 두번째 흐름이 거의 완성 단계에 왔다.
이제 smart component
인 ManageBoard.js
로 가서 mapDispatchToProps
를
수정해줘야 한다.
상단부에 action 을 호출할것이고. bindActionCreators
를 사용할것 이다.
import * as boardActions from '../../actions/boardActions'; // 선언
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(boardActions, dispatch)
}
}
그리고 콘솔만 출력하던 callWrite
함수에서 boardActions
에 있는 writeBoard
Action 을 호출 하고 호출이 성공해서 게시글 작성이 완료되면 about 으로 이동할것 이다.
this.context.router
를 호출해주기 위해서 contextTypes 정의가 필요하다.
클래스 외부에 다음과 같이 정의 한다.
ManageBoard.contextTypes = {
router: PropTypes.object.isRequired
}
callWrite
함수를 수정 한다.
callWrite(event) {
event.preventDefault();
this.props.actions.writeBoard(this.state.contents)
.then(() => this.context.router.push('/about'))
.catch(error => {
console.log(error);
})
}
그리고 지난 포스팅에서 빼먹었던 propTypes도 추가 한다.
ManageBoard.propTypes = {
contents: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired
}
여기까지 작성 하였다면 CREATE 기능 구현이 완료가 된것이다.
5번째 글은 필자가 직접 작성한 결과이다.
이번 포스팅에서는 redux에서 두번째 액션을 생성하고 이를 이용해서 CREATE 를
구현해 봤다.
다음 포스팅에서는 R에 해당되는 Read (읽기) 를 구현할 예정 이다.