流れ
1,actionで行いたい処理を記述
action/index.js
import axios from 'axios';
export const READ_MEMOS = 'READ_MEMOS'; //reducerに渡したいtypeを定数にしてexportする
export const readMemos = () => async dispatch => {
const response = await axios.get('/api/memos');
dispatch({ type: READ_MEMOS, response }); //dispatchはreducerに値を渡す人みたいなイメージ
}; //ここではreducerにactionのtypeとget通信で取得した値を渡している
2,reducerでstoreに渡す値を記述
reducers/memos.js
import _ from "lodash"; //storeにkeyを整形した値を渡したいため、lodashを使用する
import { READ_MEMOS } from "../actions";
export default (memos = [], action) => { //配列memosの中にsotoreに渡す値を格納する
switch (action.type) { // actionの定数で定義したtypeによって処理を分ける
case READ_MEMOS:
return {
memos: _.mapKeys(action.response.data.memos, "id")
//第一引数のobjecのkeyを第二引数で指定したものにする。
//_.mapKeysを使用する前、 0: {id: 1, name: "foo"} 1: {id: 2, name: "bar"}
//_.mapKeysを使用した後、 1: {id: 1, name: "foo"} 2: {id: 2, name: "bar"}
};
default:
return memos; //action.typeがない場合は何も返さない
}
};
3,combineReducersに各reducerを渡す
combineは組み合わせるという意味の英単語である
ここで各reducerを統合する
reducers/index.js
import { combineReducers } from "redux";
import lists from "./foo";
import memos from "./memos";
export default combineReducers({ foo, memos });
4,createStoreにreducerを渡す
下記のcomponentはroot componentである。
components.Index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import reducer from '../reducers/index';
export default class Index extends Component {
render() {
const store = createStore(reducer, applyMiddleware(thunk));
//第一に引数にreducer
//第二引数にapplyMiddlewareメソッドにredux-thunkを渡している。
//これをすることで、storeの機能を拡張し、非同期ロジックを記述できるおようになる。
return (
<div>
<Provider store={store}> //上記で作成したstoreで全コンポーネントをwrapすることで各コンポーネント内でstoreを使用することができる。
</Provider>
</div>
);
}
}
if (document.getElementById('index')) {
ReactDOM.render(<Index />, document.getElementById('index'));
}
5,storeに格納されている値を取り出して画面に出力させる
components/Memo.js
import React, { Component } from "react";
import { connect } from "react-redux";
import { readMemos } from "../actions";
class Top extends Component {
componentDidMount() { //componentがmountされた時にthis.props.readMemosが呼び出される
this.props.readMemos();
}
renderMemos() {
return _.map(this.props.memos, memo => ( //objectの数だけ第二引数のメソッドを繰り返す。 第二引数のmemoの値は第一引数のもの
<React.Fragment key={memo.id}>
<Button
className="text-center mt-5 pt-3 pb-3 mx-auto memo"
variant="contained"
color="secondary"
>{memo.name}
</Button>
</React.Fragment>
));
}
render() {
return (
<h2 className="text-center mt-5">メモ</h2>
{this.renderMemos()}
);
}
}
const mapStateToProps = state => ({ //reducerでreturnしたstateをこのcomponentで使用できるようにしている
memos: state.memos.memos
});
const mapDispatchToProps = { //actionで定義したreadMemosメソッドをこのcomponentで使用できるようにしている
readMemos
};
export default connect(mapStateToProps, mapDispatchToProps)(Top); //上記二つをこのcomponentで使用できるようにconnectする