Redux入門する(Providerとconnect)
現在Reactを勉強中です。Reactもまだおぼつかない状況ですが、Redux備忘録用にnoteにまとめたいと思います。
Reduxストアを作成
まず、簡単なReduxのストアを作成します。
import { createStore } from "redux"
// Reduxの状態を初期化
const initialState = {
things: []
}
function rootReducer(state, action) {
console.log("action.type", action.type)
switch (action.type) {
default:
return state
}
}
export default function configureStore() {
const store = createStore(rootReducer, initialState)
return store
}
rootReducerで定義しているconsole.log("action.type", action.type)が出力されれば、とりあえずReduxへの接続が成功しているとわかる様にします。
次に、App.jsxにHelloWorldコンポーネントを置きます。
import React from "react"
import { BrowserRouter, Switch, Route } from 'react-router-dom'
import { Provider } from 'react-redux'
import HelloWorld from './HelloWorld'
import configureStore from '../configureStore'
const store = configureStore()
class App extends React.Component {
render () {
return (
// ここでストアと接続
<Provider store={store}>
<BrowserRouter>
<Switch>
<Route path="/" render={() => <HelloWorld />} />
</Switch>
</BrowserRouter>
</Provider>
);
}
}
export default App
ここで躓くポイント1がきました
Providerってなに
①Reactコンポーネント内でreact-reduxのconnect()関数を使えるようにする
②ラップしたコンポーネントにstore情報を渡す
引用:https://qiita.com/MegaBlackLabel/items/df868e734d199071b883
説明が分かりやすい!つまり、今回のコードでいうと、HelloWorldコンポーネントでconnect()関数を使える様にする(①)、HelloWorldコンポーネントにconfigureStore(先ほど作成したReduxストア)を渡す(②)ということかなぁ
なんとなくの理解なので、理解を深めるためにHelloWorldコンポーネントの中身も書いていきます。
import React from "react"
import { connect } from 'react-redux'
import { createStructuredSelector } from 'reselect'
const GET_THINGS_REQUEST = 'GET_THINGS_REQUEST'
function getThings() {
console.log('getTings action')
return {
type: GET_THINGS_REQUEST
}
}
class HelloWorld extends React.Component {
render () {
return (
<React.Fragment>
<button className="getThingsBtn" onClick={() => this.props.getThings()}>getThings</button>
</React.Fragment>
);
}
}
const structuredSelector = createStructuredSelector({
things: state => state.things,
})
const mapDispatchToProps = { getThings }
// HelloWorldコンポーネントにマッピング
export default connect(structuredSelector, mapDispatchToProps)(HelloWorld)
ここで躓くポイント2、きた・・
connectってなに
上記のコードの一番下のやつ
export default connect(structuredSelector, mapDispatchToProps)(HelloWorld)
最後にHelloWorldコンポーネントを指定しているのはわかるけど、connectの引数が謎・・。
connectとは、Reduxの「store」にReactがアクセスするための関数
ちょっとググったらこんな説明がありました。なるほど。
そしてconnectに渡す引数によって挙動が少しずつ変わるらしいのです。
connect() Parameters
function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)
公式の説明が分かりやすかったので、日本語にしておきます
・mapStateToProps|第一引数
ストアが更新されるたび呼び出される関数
コンポーネントにマージされるのでプレーンオブジェクトである必要がある
変更検知したくない場合は、nullかundefinedをmapStateToPropsの変わりに指定
[example]
const mapStateToProps = state => ({ todos: state.todos })
・mapDispatchToProps|第二引数
mapDispatchToProps(dispatch, ownProps) ※ownPropsは任意で指定
dispatchを通じてstateを書き換えます
詳しく見ていったら、なんとなく理解ができました👀
でもまだ分からない・・。connectは分かったけど、第一引数で渡している関数の中のcreateStructuredSelector ってなになの
createStructuredSelector(reduxjs/reselect)
Reduxのセレクタのライブラリらしいですね〜
つまり、今回のコードだと・・
const structuredSelector = createStructuredSelector({
things: state => state.things,
})
thingsにstate.thingsを割り当てているのですね。
なぜcreateStructuredSelectorを使うと嬉しいのかは、まだ理解できていません・・。
コードの理解はまだまだですが、とりあえず目標にしていた「ボタンを押した時に、Reduxと接続する」ができました!