connect()
connect
はReact-Redux 8.xでも動作し、サポートされています。ただし、フックAPIをデフォルトとして使用することをお勧めします。
概要
connect()
関数は、ReactコンポーネントをReduxストアに接続します。
ストアから必要なデータの一部と、ストアにアクションをディスパッチするために使用できる関数を、接続されたコンポーネントに提供します。
渡されたコンポーネントクラスを変更するのではなく、渡されたコンポーネントをラップする新しい接続済みコンポーネントクラスを返します。
function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)
mapStateToProps
と mapDispatchToProps
は、それぞれReduxストアの state
と dispatch
を処理します。state
と dispatch
は、最初の引数としてmapStateToProps
または mapDispatchToProps
関数に渡されます。
mapStateToProps
と mapDispatchToProps
の戻り値は、内部的にはそれぞれ stateProps
と dispatchProps
と呼ばれます。これらは、定義されている場合は最初の引数と2番目の引数としてmergeProps
に渡され、3番目の引数は ownProps
となります。結合された結果(一般的に mergedProps
と呼ばれます)は、接続されたコンポーネントに渡されます。
connect()
パラメータ
connect
は、すべてオプションの4つの異なるパラメータを受け入れます。慣例により、それらは次のように呼び出されます。
mapStateToProps?: Function
mapDispatchToProps?: Function | Object
mergeProps?: Function
options?: Object
mapStateToProps?: (state, ownProps?) => Object
mapStateToProps
関数が指定されている場合、新しいラッパーコンポーネントはReduxストアの更新を購読します。つまり、ストアが更新されるたびに、mapStateToProps
が呼び出されます。mapStateToProps
の戻り値はプレーンオブジェクトでなければならず、それはラップされたコンポーネントのプロパティにマージされます。ストアの更新を購読したくない場合は、mapStateToProps
の代わりにnull
またはundefined
を渡します。
パラメータ
state: Object
ownProps?: Object
mapStateToProps
関数は、最大2つのパラメータを取ります。宣言された関数パラメータの数(別名アリティ)は、それがいつ呼び出されるかに影響します。これは、関数がownPropsを受け取るかどうかも決定します。詳細はこちらを参照してください。
state
mapStateToProps
関数が1つのパラメータを取るように宣言されている場合、ストアの状態が変更されるたびに呼び出され、ストアの状態が唯一のパラメータとして渡されます。
const mapStateToProps = (state) => ({ todos: state.todos })
ownProps
mapStateToProps
関数が2つのパラメータを取るように宣言されている場合、ストアの状態が変更された時、またはラッパーコンポーネントが新しいプロパティを受け取った時(浅い等価比較に基づく)に呼び出されます。ストアの状態が最初の引数として、ラッパーコンポーネントのプロパティが2番目の引数として渡されます。
2番目のパラメータは、通常、慣例によりownProps
と呼ばれます。
const mapStateToProps = (state, ownProps) => ({
todo: state.todos[ownProps.id],
})
戻り値
mapStateToProps
関数はオブジェクトを返すことが期待されています。このオブジェクトは、通常stateProps
と呼ばれ、接続されたコンポーネントのプロパティとしてマージされます。mergeProps
を定義する場合、それはmergeProps
の最初のパラメータとして渡されます。
mapStateToProps
の戻り値は、接続されたコンポーネントが再レンダリングされるかどうかを決定します(詳細はこちら)。
mapStateToProps
の推奨される使用方法の詳細については、mapStateToProps
の使い方に関するガイドを参照してください。
mapStateToProps
とmapDispatchToProps
をファクトリ関数として定義できます。つまり、オブジェクトではなく関数を返します。この場合、返された関数は実際のmapStateToProps
またはmapDispatchToProps
として扱われ、後続の呼び出しで呼び出されます。ファクトリ関数に関するメモ、またはパフォーマンス最適化に関するガイドを参照してください。
mapDispatchToProps?: Object | (dispatch, ownProps?) => Object
慣例的にmapDispatchToProps
と呼ばれ、connect()
の2番目のパラメータは、オブジェクト、関数、または何も供給されない場合があります。
connect()
に2番目のパラメータを供給しない場合、コンポーネントはデフォルトでdispatch
を受け取ります。
// do not pass `mapDispatchToProps`
connect()(MyComponent)
connect(mapState)(MyComponent)
connect(mapState, null, mergeProps, options)(MyComponent)
mapDispatchToProps
を関数として定義する場合、最大2つのパラメータで呼び出されます。
パラメータ
dispatch: Function
ownProps?: Object
dispatch
mapDispatchToProps
が1つのパラメータを取る関数として宣言されている場合、ストアのdispatch
が渡されます。
const mapDispatchToProps = (dispatch) => {
return {
// dispatching plain actions
increment: () => dispatch({ type: 'INCREMENT' }),
decrement: () => dispatch({ type: 'DECREMENT' }),
reset: () => dispatch({ type: 'RESET' }),
}
}
ownProps
mapDispatchToProps
関数が2つのパラメータを取るように宣言されている場合、dispatch
が最初のパラメータとして、ラッパーコンポーネントに渡されたプロパティが2番目のパラメータとして渡され、接続されたコンポーネントが新しいプロパティを受け取るたびに再呼び出されます。
2番目のパラメータは、通常、慣例によりownProps
と呼ばれます。
// binds on component re-rendering
<button onClick={() => this.props.toggleTodo(this.props.todoId)} />
// binds on `props` change
const mapDispatchToProps = (dispatch, ownProps) => ({
toggleTodo: () => dispatch(toggleTodo(ownProps.todoId)),
})
mapDispatchToProps
の宣言された関数パラメータの数によって、ownPropsを受け取るかどうかが決まります。詳細はこちらを参照してください。
戻り値
mapDispatchToProps
関数はオブジェクトを返すことが期待されています。オブジェクトの各フィールドは関数であり、それを呼び出すことでストアにアクションがディスパッチされることが期待されます。
mapDispatchToProps
関数の戻り値はdispatchProps
とみなされます。それは接続されたコンポーネントのプロパティとしてマージされます。mergeProps
を定義する場合、それはmergeProps
の2番目のパラメータとして渡されます。
const createMyAction = () => ({ type: 'MY_ACTION' })
const mapDispatchToProps = (dispatch, ownProps) => {
const boundActions = bindActionCreators({ createMyAction }, dispatch)
return {
dispatchPlainObject: () => dispatch({ type: 'MY_ACTION' }),
dispatchActionCreatedByActionCreator: () => dispatch(createMyAction()),
...boundActions,
// you may return dispatch here
dispatch,
}
}
推奨される使用方法の詳細については、mapDispatchToProps
の使い方に関するガイドを参照してください。
mapStateToProps
とmapDispatchToProps
をファクトリ関数として定義できます。つまり、オブジェクトではなく関数を返します。この場合、返された関数は実際のmapStateToProps
またはmapDispatchToProps
として扱われ、後続の呼び出しで呼び出されます。ファクトリ関数に関するメモ、またはパフォーマンス最適化に関するガイドを参照してください。
オブジェクト簡略記法
mapDispatchToProps
は、各フィールドがアクションクリエイターであるオブジェクトにすることができます。
import { addTodo, deleteTodo, toggleTodo } from './actionCreators'
const mapDispatchToProps = {
addTodo,
deleteTodo,
toggleTodo,
}
export default connect(null, mapDispatchToProps)(TodoApp)
この場合、React-ReduxはbindActionCreators
を使用して、ストアのdispatch
を各アクションクリエイターにバインドします。結果はdispatchProps
とみなされ、接続されたコンポーネントに直接マージされるか、または2番目の引数としてmergeProps
に渡されます。
// internally, React-Redux calls bindActionCreators
// to bind the action creators to the dispatch of your store
bindActionCreators(mapDispatchToProps, dispatch)
オブジェクト簡略記法の使用方法については、mapDispatchToProps
ガイドのこちらのセクションもご覧ください。
mergeProps?: (stateProps, dispatchProps, ownProps) => Object
指定されている場合、ラップされたコンポーネントの最終的なプロパティの決定方法を定義します。mergeProps
を提供しない場合、ラップされたコンポーネントはデフォルトで{ ...ownProps, ...stateProps, ...dispatchProps }
を受け取ります。
パラメータ
mergeProps
は最大3つのパラメータで指定する必要があります。それらはそれぞれ、mapStateToProps()
、mapDispatchToProps()
、およびラッパーコンポーネントのprops
の結果です。
stateProps
dispatchProps
ownProps
そこから返すプレーンオブジェクトのフィールドは、ラップされたコンポーネントのプロパティとして使用されます。この関数を指定して、プロパティに基づいて状態のスライスを選択したり、アクションクリエイターをプロパティの特定の変数にバインドしたりできます。
戻り値
mergeProps
の戻り値はmergedProps
と呼ばれ、そのフィールドはラップされたコンポーネントのプロパティとして使用されます。
注:
mergeProps
で新しい値を作成すると、再レンダリングが発生します。不要な再レンダリングを避けるために、フィールドをメモ化することをお勧めします。
options?: Object
{
context?: Object,
areStatesEqual?: Function,
areOwnPropsEqual?: Function,
areStatePropsEqual?: Function,
areMergedPropsEqual?: Function,
forwardRef?: boolean,
}
context: Object
注記: このパラメータはv6.0以降でサポートされています。
React-Redux v6では、React-Reduxで使用されるカスタムコンテキストインスタンスを指定できます。 カスタムコンテキストのインスタンスを<Provider />
と接続されたコンポーネントの両方に渡す必要があります。接続されたコンポーネントへのコンテキストの渡し方は、オプションのフィールドとしてここで渡すか、レンダリング時にプロップとして接続されたコンポーネントに渡すかの2通りがあります。
// const MyContext = React.createContext();
connect(mapStateToProps, mapDispatchToProps, null, { context: MyContext })(
MyComponent,
)
areStatesEqual: (next: Object, prev: Object, nextOwnProps: Object, prevOwnProps: Object) => boolean
- デフォルト値:
strictEqual: (next, prev) => prev === next
受信したストアの状態を以前の値と比較します。
const areStatesEqual = (next, prev) =>
prev.entities.todos === next.entities.todos
mapStateToProps
関数が計算コストが高く、状態のごく一部しか考慮していない場合、areStatesEqual
をオーバーライドすることを検討してください。 上記の例では、状態の一部の変更以外は無視されます。さらに、areStatesEqual
はnextOwnProps
とprevOwnProps
を提供するため、必要に応じて、接続されたコンポーネントが関心を持つ状態のスコープをより効果的に設定できます。
これは、mapStateToProps
関数に応じて、他の等価性チェックにも影響を与える可能性があります。
areOwnPropsEqual: (next: Object, prev: Object) => boolean
- デフォルト値:
shallowEqual: (objA, objB) => boolean
(オブジェクトの各フィールドが等しい場合にtrue
を返します)
受信したプロップを以前の値と比較します。
受信プロップをホワイトリスト登録する方法として、areOwnPropsEqual
をオーバーライドすることを検討してください。 その場合、mapStateToProps
、mapDispatchToProps
、mergeProps
も実装してプロップをホワイトリスト登録する必要があります。(例えば、recomposeのmapPropsを使用するなど、他の方法で実現する方が簡単かもしれません。)
areStatePropsEqual: (next: Object, prev: Object) => boolean
- 型:
function
- デフォルト値:
shallowEqual
mapStateToProps
の結果を以前の値と比較します。
areMergedPropsEqual: (next: Object, prev: Object) => boolean
- デフォルト値:
shallowEqual
mergeProps
の結果を以前の値と比較します。
mapStateToProps
が、関連プロップが変更された場合にのみ新しいオブジェクトを返すメモ化されたセレクタを使用している場合、areStatePropsEqual
をオーバーライドしてstrictEqual
を使用することを検討してください。これにより、mapStateToProps
が呼び出されるたびに個々のプロップで追加の等価性チェックを回避できるため、わずかなパフォーマンス向上になります。
セレクタが複雑なプロップ(例:ネストされたオブジェクト、新しい配列など)を生成する場合、areMergedPropsEqual
をオーバーライドしてdeepEqual
を実装することを検討してください。(ディープイコールチェックは、再レンダリングするよりも高速な場合があります。)
forwardRef: boolean
注記: このパラメータはv6.0以降でサポートされています。
{forwardRef: true}
がconnect
に渡された場合、接続されたラッパーコンポーネントへの参照を追加すると、実際にはラップされたコンポーネントのインスタンスが返されます。
connect()
の戻り値
connect()
の戻り値は、コンポーネントを受け取り、注入する追加のプロップを含むラッパーコンポーネントを返すラッパー関数です。
import { login, logout } from './actionCreators'
const mapState = (state) => state.user
const mapDispatch = { login, logout }
// first call: returns a hoc that you can use to wrap any component
const connectUser = connect(mapState, mapDispatch)
// second call: returns the wrapper component with mergedProps
// you may use the hoc to enable different components to get the same behavior
const ConnectedUserLogin = connectUser(Login)
const ConnectedUserProfile = connectUser(Profile)
ほとんどの場合、ラッパー関数は一時変数に保存されることなく、すぐに呼び出されます。
import { login, logout } from './actionCreators'
const mapState = (state) => state.user
const mapDispatch = { login, logout }
// call connect to generate the wrapper function, and immediately call
// the wrapper function to generate the final wrapper component.
export default connect(mapState, mapDispatch)(Login)
使用例
connect
は非常に柔軟であるため、その呼び出し方法の追加例を参照すると役立つ場合があります。
dispatch
のみを注入し、ストアを監視しません。
export default connect()(TodoApp)
- ストアを購読せずに、すべてのaction creator(
addTodo
、completeTodo
など)を注入します。
import * as actionCreators from './actionCreators'
export default connect(null, actionCreators)(TodoApp)
dispatch
とグローバル状態のすべてのフィールドを注入します。
これは行わないでください!
TodoApp
は状態の変更のたびに再レンダリングされるため、パフォーマンスの最適化がすべて無効になります。ビュー階層内の複数のコンポーネントに、関連する状態のスライスのみを監視するより粒度の細かいconnect()
を使用する方が優れています。
// don't do this!
export default connect((state) => state)(TodoApp)
dispatch
とtodos
を注入します。
function mapStateToProps(state) {
return { todos: state.todos }
}
export default connect(mapStateToProps)(TodoApp)
todos
とすべてのaction creatorを注入します。
import * as actionCreators from './actionCreators'
function mapStateToProps(state) {
return { todos: state.todos }
}
export default connect(mapStateToProps, actionCreators)(TodoApp)
todos
とすべてのaction creator(addTodo
、completeTodo
など)をactions
として注入します。
import * as actionCreators from './actionCreators'
import { bindActionCreators } from 'redux'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return { actions: bindActionCreators(actionCreators, dispatch) }
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
todos
と特定のaction creator(addTodo
)を注入します。
import { addTodo } from './actionCreators'
import { bindActionCreators } from 'redux'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ addTodo }, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
todos
と特定のaction creator(addTodo
とdeleteTodo
)を省略記法で注入します。
import { addTodo, deleteTodo } from './actionCreators'
function mapStateToProps(state) {
return { todos: state.todos }
}
const mapDispatchToProps = {
addTodo,
deleteTodo,
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
todos
、todoActionCreators
をtodoActions
として、counterActionCreators
をcounterActions
として注入します。
import * as todoActionCreators from './todoActionCreators'
import * as counterActionCreators from './counterActionCreators'
import { bindActionCreators } from 'redux'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return {
todoActions: bindActionCreators(todoActionCreators, dispatch),
counterActions: bindActionCreators(counterActionCreators, dispatch),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
todos
、todoActionCreators
とcounterActionCreators
をまとめてactions
として注入します。
import * as todoActionCreators from './todoActionCreators'
import * as counterActionCreators from './counterActionCreators'
import { bindActionCreators } from 'redux'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(
{ ...todoActionCreators, ...counterActionCreators },
dispatch,
),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
todos
、すべてのtodoActionCreators
とcounterActionCreators
をプロップとして直接注入します。
import * as todoActionCreators from './todoActionCreators'
import * as counterActionCreators from './counterActionCreators'
import { bindActionCreators } from 'redux'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{ ...todoActionCreators, ...counterActionCreators },
dispatch,
)
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
- プロップに応じて特定のユーザーの
todos
を注入します。
import * as actionCreators from './actionCreators'
function mapStateToProps(state, ownProps) {
return { todos: state.todos[ownProps.userId] }
}
export default connect(mapStateToProps)(TodoApp)
- プロップに応じて特定のユーザーの
todos
を注入し、アクションにprops.userId
を注入します。
import * as actionCreators from './actionCreators'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mergeProps(stateProps, dispatchProps, ownProps) {
return Object.assign({}, ownProps, {
todos: stateProps.todos[ownProps.userId],
addTodo: (text) => dispatchProps.addTodo(ownProps.userId, text),
})
}
export default connect(mapStateToProps, actionCreators, mergeProps)(TodoApp)
注記
mapToProps
関数の引数の数
mapStateToProps
とmapDispatchToProps
の宣言された関数パラメータの数は、それらがownProps
を受け取るかどうかを決定します。
注記: 関数の正式な定義に必須パラメータが1つだけ含まれている場合(関数のlengthが1の場合)、
ownProps
はmapStateToProps
とmapDispatchToProps
に渡されません。 例えば、以下のように定義された関数は、第2引数としてownProps
を受け取りません。ownProps
の入力値がundefined
の場合、デフォルトの引数値が使用されます。
function mapStateToProps(state) {
console.log(state) // state
console.log(arguments[1]) // undefined
}
const mapStateToProps = (state, ownProps = {}) => {
console.log(state) // state
console.log(ownProps) // {}
}
必須パラメータがないか、2つのパラメータを持つ関数*はownProps
を受け取ります。
const mapStateToProps = (state, ownProps) => {
console.log(state) // state
console.log(ownProps) // ownProps
}
function mapStateToProps() {
console.log(arguments[0]) // state
console.log(arguments[1]) // ownProps
}
const mapStateToProps = (...args) => {
console.log(args[0]) // state
console.log(args[1]) // ownProps
}
ファクトリ関数
mapStateToProps
またはmapDispatchToProps
関数が関数を返す場合、コンポーネントのインスタンス化時に1回呼び出され、その戻り値が、後続の呼び出しでの実際のmapStateToProps
、mapDispatchToProps
関数としてそれぞれ使用されます。
ファクトリ関数は、通常、メモ化されたセレクタで使用されます。これにより、クロージャ内でコンポーネントインスタンス固有のセレクタを作成できます。
const makeUniqueSelectorInstance = () =>
createSelector([selectItems, selectItemId], (items, itemId) => items[itemId])
const makeMapState = (state) => {
const selectItemForThisComponent = makeUniqueSelectorInstance()
return function realMapState(state, ownProps) {
const item = selectItemForThisComponent(state, ownProps.itemId)
return { item }
}
}
export default connect(makeMapState)(SomeComponent)
レガシーバージョンのドキュメント
connect
APIは、すべての主要バージョン間でほぼ完全にAPI互換性を維持してきましたが、バージョンごとにオプションと動作に小さな変更がありました。
レガシーバージョン5.xと6.xの詳細については、React Reduxリポジトリにあるこれらのアーカイブファイルを参照してください。