React-Reduxの説明されているページなどでは大体例としてFunctional Componentでしか説明されていなくて
Class Componentでどうやって繋ぐのかという具体例がほとんど見当たらなかった
慣れてる人から見れば他愛もない問題なのかも知れないけれど個人的にはちょっと苦戦したので執筆
Class Componentじゃなきゃコンポーネントマウント・アンマウント時になどのタイミングで呼ばれるライフサイクルメソッドを定義する場合に不便だったり(認識誤りかも知れないけれど)、元のコンポーネントをClass Componentとして定義しててそれをReact-Reduxに繋ぎたい場合だったりなどなど
→【追記】ver16.8で追加されたReact Hooksを使えばFunctional Componentでも同等の事ができそう
準備
今回Functional ComponentからClass Componentへ書き換えるというアプローチを行い書き換え元として
connected-react-routerのexamples/basicを利用する
これをダウンロードして普通に起動する場合
コマンドプロンプトやターミナルなどでexamples/basicへ行き
npm install で依存関係を解決し
npm start でサーバーを起動
ブラウザから http://localhost:8080 へアクセスすると以下の様な画面が表示される
この中でCounterの部分でReduxを使用していて
ここで[+]ボタンを押すとカウントアップされ
このカウントアップされた値はストアに格納されているのでReact Router経由の他の画面のに移動して
戻ってきても値が保持されている
この動作をReduxでの保存の動作の指針とした
実際の書き換え
今回書き換えはこのCounterのComponentが定義されているexamples/basic/src/components/Counter.jsファイルに対して行う
散々試行錯誤した結果書き換えが必要な個所はこれだけだった
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { increment, decrement } from '../actions/counter'
-const Counter = (props) => (
- <div>
- Counter: {props.count}
- <button onClick={props.increment}>+</button>
- <button onClick={props.decrement}>-</button>
- </div>
-)
+class Counter extends React.Component {
+ constructor(props) {
+ super(props);
+ }
+ render(){
+ return (
+ <div>
+ Counter: {this.props.count}
+ <button onClick={this.props.increment}>+</button>
+ <button onClick={this.props.decrement}>-</button>
+ </div>
+ );
+ }
+}
Counter.propTypes = {
count: PropTypes.number,
increment: PropTypes.func.isRequired,
decrement: PropTypes.func.isRequired,
}
const mapStateToProps = state => ({
count: state.count,
})
const mapDispatchToProps = dispatch => ({
increment: () => dispatch(increment()),
decrement: () => dispatch(decrement()),
})
export default connect(mapStateToProps, mapDispatchToProps)(Counter)
主な変更点としては
本体JSXはrender()の戻り値に指定
アロー関数の引数はpropsはconstructor()からsuper()に渡す
superに渡されたpropsはclass内ではthis.propsとなる