ReduxでmapToDispatchToProps()への引数が指定されている場合、「ディスパッチ」は関数ではありません


124

私はjavascript / redux / reactの初心者で、redux、react-redux、reactを使用して小さなアプリケーションを作成しています。何らかの理由で、connect(react-reduxバインディング)と並行してmapDispatchToProps関数を使用すると、結果のプロップを実行しようとすると、ディスパッチが関数ではないことを示すTypeErrorが表示されます。ただし、ディスパッチを小道具として呼び出すと(提供されたコードのsetAddr関数を参照)、機能します。

なぜなのか、私は知りたいのですが、reduxドキュメントのTODOアプリの例では、mapDispatchToPropsメソッドが同じ方法で設定されています。関数内のconsole.log(dispatch)は、ディスパッチがオブジェクト型であると述べています。この方法でディスパッチを使い続けることもできますが、reduxをさらに続行する前に、なぜこれが起こっているのかを理解するのが良いでしょう。私はコンパイルにbabel-loadersでwebpackを使用しています。

私のコード:

import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import { setAddresses } from '../actions.js';
import GeoCode from './geoCode.js';
import FlatButton from 'material-ui/lib/flat-button';

const Start = React.createClass({
    propTypes: {
        onSubmit: PropTypes.func.isRequired
    },

    setAddr: function(){
        this.props.dispatch(
            setAddresses({
                pickup: this.refs.pickup.state.address,
                dropoff: this.refs.dropoff.state.address
            })
        )   

    },

    render: function() {
        return (
            <div>
                <div className="row">
                    <div className="col-xs-6">
                        <GeoCode ref='pickup' />
                    </div>
                    <div className="col-xs-6">
                        <GeoCode ref='dropoff' />
                    </div>
                </div>
                <div className="row">
                    <div className="col-xs-6">
                        <FlatButton 
                            label='Does Not Work'
                            onClick={this.props.onSubmit({
                                pickup: this.refs.pickup.state.address,
                                dropoff: this.refs.dropoff.state.address
                            })} 
                            />
                    </div>
                    <div className="col-xs-6">
                        <FlatButton 
                            label='Works'
                            onClick={this.setAddr} 
                            />
                    </div>
                </div>
            </div>
        );
    }
})

const mapDispatchToProps = (dispatch) => {
    return {
        onSubmit: (data) => {
            dispatch(setAddresses(data))
        }
    }
}

const StartContainer = connect(mapDispatchToProps)(Start)

export default StartContainer

乾杯。


私はこの問題を持っていたし、これは私がそれを解決する助けた
アレックスW

回答:


249

最初の引数を単に使用mapDispatchToPropsせずに使用したい場合。mapStateToPropsnull

export default connect(null, mapDispatchToProps)(Start)


4
これは私が探していたものです。これで、いくつかのアクションをディスパッチしたいかどうかがわかります。
皇帝クラウザー2017年

これはまさに私が探していたものです。完璧な解決策をありがとう。どのコンポーネントでもmapDispatchToPropsを使用する必要がない場合はどうなりますか?そのシナリオを処理する必要があるのと同じ方法ですか?
アルンラマチャンドラン2018年

1
あなたが必要としない場合はmapDispatchToProps、ちょうどにその引数を追加しないでくださいconnectconnect(mapStateToProps)(MyComponent)
inostia

107

メソッドconnectであるへの最初の引数が不足していますmapStateToProps。Redux todoアプリからの抜粋:

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

3
この方法を使用することは必須ですか?このメソッドは状態をキャッチするだけで、このメソッドが必要ない場合はどうなりますか?
Muneem Habib 2016

6
@MuneemHabib不要な場合にこのメソッドを提供しない方法についてはinostiaの回答を参照してください
Brandon

21

使用する

const StartContainer = connect(null, mapDispatchToProps)(Start) 

の代わりに

const StartContainer = connect(mapDispatchToProps)(Start)

5

私は引数を交換することでそれを解決しました、私は使っていました

export default connect(mapDispatchToProps, mapStateToProps)(Checkbox)

それは間違っています。mapStateToProps最初の引数である必要があります。

export default connect(mapStateToProps, mapDispatchToProps)(Checkbox)

今では当たり前に聞こえますが、誰かを助けるかもしれません。


3

私はReact.Componentそれを投稿しているので、使用例が必要でした:

import React from 'react';
import * as Redux from 'react-redux';

class NavigationHeader extends React.Component {

}

const mapStateToProps = function (store) {
    console.log(`mapStateToProps ${store}`);
    return {
        navigation: store.navigation
    };
};

export default Redux.connect(mapStateToProps)(NavigationHeader);

3

問題

ここでは、コード内の接続コンポーネントの動作を理解するために注意すべき点をいくつか示します。

問題のアリティconnectconnect(mapStateToProps, mapDispatchToProps)

React-Reduxはconnect、最初の引数mapStateToPropsと2番目の引数を使用して呼び出しますmapDispatchToProps

したがって、を渡したとしてもmapDispatchToProps、React-Reduxは実際にはそれをmapState最初の引数として扱うため、onSubmitの戻り値がmapStateコンポーネントのプロップにマージされるため、コンポーネントに注入された関数を取得できます。しかし、それはmapDispatch注入方法ではありません。

mapDispatch定義せずに使用できmapStateます。のnull代わりに渡すmapStateと、コンポーネントはストアの変更の影響を受けません。

接続されたコンポーネントが提供されていdispatchない場合のデフォルトの受信mapDispatch

また、コンポーネントはの2番目の位置を受け取ったdispatchので受け取ります。正しく渡すと、コンポーネントは受け取りません。nullmapDispatchmapDispatchdispatch

一般的な方法

上記は、コンポーネントがそのように動作した理由を答えています。ただし、mapStateToPropsのオブジェクトの省略表現を使用して、アクションクリエーターに渡すだけの方法が一般的です。そして、あなたのコンポーネントのonSubmitそれは次のとおりです:

import { setAddresses } from '../actions.js'

const Start = (props) => {
  // ... omitted
  return <div>
    {/** omitted */}
    <FlatButton 
       label='Does Not Work'
       onClick={this.props.setAddresses({
         pickup: this.refs.pickup.state.address,
         dropoff: this.refs.dropoff.state.address
       })} 
    />
  </div>
};

const mapStateToProps = { setAddresses };
export default connect(null, mapDispatchToProps)(Start)

0

mapDispatchToProps次のように、2番目の引数として指定しない場合:

export default connect(mapStateToProps)(Checkbox)

次に、コンポーネントのプロップへのディスパッチを自動的に取得するので、次のことができます。

class SomeComp extends React.Component {
  constructor(props, context) {
    super(props, context);
  }
  componentDidMount() {
    this.props.dispatch(ACTION GOES HERE);
  }
....

mapDispatchToPropsなし


0

私はこのように使用しています。最初の引数はmapStateToPropsで、2番目の引数は関数/クラスとの最後のmapDispatchToPropsです。

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

export default connect(mapStateToProps,mapDispatchToProps)(TodoList);

あなたが最初の引数を持っていけないならば、ちょうど..ヌル/未定義した後、第2引数を渡す
アブドゥルMoiz

0

このエラーは、接続に渡されているときにコンポーネント関数の順序を変更したときにも発生します。

間違った順序:

export default connect(mapDispatchToProps, mapStateToProps)(TodoList);

正しい順番:

export default connect(mapStateToProps,mapDispatchToProps)(TodoList);

0

一部の人が踏み込む可能性のある落とし穴は、この質問でカバーされていますが、コード構造はわずかに異なりますがまったく同じエラーを返すため、回答では扱われません。

このエラーはbindActionCreatorsdispatch関数を使用して渡さない場合に発生します

エラーコード

import someComponent from './someComponent'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'
import { someAction } from '../../../actions/someAction'

const mapStatToProps = (state) => {
    const { someState } = state.someState

    return {
        someState
    }
};

const mapDispatchToProps = (dispatch) => {
    return bindActionCreators({
        someAction
    });
};

export default connect(mapStatToProps, mapDispatchToProps)(someComponent)

固定コード

import someComponent from './someComponent'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'
import { someAction } from '../../../actions/someAction'

const mapStatToProps = (state) => {
    const { someState } = state.someState

    return {
        someState
    }
};

const mapDispatchToProps = (dispatch) => {
    return bindActionCreators({
        someAction
    }, dispatch);
};

export default connect(mapStatToProps, mapDispatchToProps)(someComponent)

dispatchエラーコードに関数がありませんでした


0

React-reduxの 'connect'関数は2つの引数を受け入れます。1つはmapStateToPropsで、もう1つは以下のmapDispatchToPropsチェックです。

export default connect(mapStateToProps, mapDispatchToProps)(Index); `

reduxから状態を取得したくない場合は、mapStateToPropsの代わりにnullを設定します。

export default connect(null, mapDispatchToProps)(Index);

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.