ReactとReduxでカウンターアプリを作る
今回はReactとReduxで簡単なカウンターアプリを作ってみます。
Reduxを学んで3日目なので間違っているかもしれません。
Reduxを使うにはまず以下のコマンドでReduxに必要なモジュールをインポートしておきます。
npm install redux npm install react-redux
ファイル構成はsrc内に以下のファイルがあります。
・Actions.js
・Reducres.js
・index.js
・App.js
まずActions.jsから書いていきます。
//Actions.js //Action type const INCREMENT="INCREMENT"; const DECREMENT="DECREMENT"; //Action Creater const increment =()=>{ return{type:INCREMENT}; }; const decrement =()=>{ return{type:DECREMENT}; }; export {increment,decrement}; export {INCREMENT,DECREMENT};
ここにはAction typeとAction Creatorをかいてあります。書き方はたくさんあり以下の書き方でも大丈夫です。好きな書き方を選んでください。
//typeに直接書く const increment =()=>{ return type:”INCREMENT”; }; const decrement =()=>{ return type:"DECREMENT”; }; //関数で書く function increment(){ return{type:INCREMENT}; } function decrement(){ return{type:DECREME}; }
ちなみにtypeはconstで定数化するのがツウらしいので今回はそうしてあります。
次はReducres.jsを書いていきます。
//Reducres.js import { combineReducers } from "redux"; import {INCREMENT,DECREMENT} from './Action'; const initialState = { count: 0 }; //Reducer const counter = (state = initialState, action) => { switch(action.type){ case INCREMENT: return { ...state, count: state.count + 1} case DECREMENT: return { ...state, count: state.count - 1} default: return state } } const reducers=combineReducers({counter}); export default reducers;
Reducers.jsにはReducerを書いています。
Reducerはswitch文を使ってActionごとに処理を実行します。
Reactではstateを直接変更してはいけないルールがあるのでコピーしてから変更します。
本来combineReducersは複数のReducerをまとめるために使うのですが、慣れるために今回は使っています。
次にindex.jsを書いていきます。
//index.js import React from 'react'; import ReactDOM from 'react-dom'; import { createStore } from 'redux'; import { Provider } from 'react-redux'; import App from './App'; import reducers from './Reducres'; import * as serviceWorker from './serviceWorker'; const store = createStore(reducers); ReactDOM. render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') ); serviceWorker.unregister();
creatStoreでStoreを作ります。引数には先程作ったReducerをいれます。
そして、コンポーネントを
最後にApp.jsを書いていきます。
//App.js import React from 'react'; import { connect } from 'react-redux' import { increment, decrement } from './Action'; class App extends React.Component{ render(){ return( <div> <p>Count:{this.props.count}</p> <button onClick={this.props.increment}>+</button> <button onClick={this.props.decrement}>-</button> </div> ); } } const mapStateToProps = (state) =>{ return {count: state.counter.count} } const mapDispatchToProps = (dispatch) =>( { increment: () => dispatch(increment()), decrement: () => dispatch(decrement()) } ) export default connect(mapStateToProps, mapDispatchToProps)(App);
mapStateToPropsではstateをpropsに変換して返します。
今回はReducerのcounter関数のcountというstateが欲しいのでこのように書いています。
mapDispatchToPropsではdiapatchを使うために書いてあります。とりあえず、何かしらのアクション(カウント増やす、減らすなど)をする場合には書いておけば大丈夫だと思います。
diapatchの引数にはAction Creatorを入れることで、その情報がcreateStoreで登録したreducerに送られ、Action typeごとに処理を実行します。ここは自己解釈なので正しいかはわかりません。
最後のconnectはコンポーネントを引数にいれ、mapStateToProps, mapDispatchToPropsを引数のコンポーネントと結びつけています。
本当はApp.jsは描画するだけのコンポーネントにしたかったのですが、connect関数やmapStateToProps を別のファイルに分けてApp.jsに読み込ませる方法がわからなかったのでこのようにしました。分ける方法が分かったら追記するかもしれません。
これで終わりです。
追記:GitHubに挙げときました。Gitとかの使い方が分からなかったのでソースコードのみになります。
https://github.com/matsudasan/counter