'dispatch' ist keine Funktion, wenn ein Argument für mapToDispatchToProps () in Redux vorliegt

123

Ich bin ein Javascript / Redux / React-Anfänger, der eine kleine Anwendung mit Redux, React-Redux und React erstellt. Aus irgendeinem Grund erhalte ich bei Verwendung der Funktion mapDispatchToProps in Verbindung mit connect (React-Redux-Bindung) einen TypeError, der angibt, dass der Versand keine Funktion ist, wenn ich versuche, die resultierende Requisite auszuführen. Wenn ich den Versand jedoch als Requisite aufrufe (siehe die Funktion setAddr im bereitgestellten Code), funktioniert es.

Ich bin gespannt, warum dies so ist. In der TODO-Beispiel-App in den Redux-Dokumenten wird die mapDispatchToProps-Methode auf die gleiche Weise eingerichtet. Wenn ich console.log (dispatch) innerhalb der Funktion habe, heißt es, dass dispatch vom Typ object ist. Ich könnte den Versand weiterhin auf diese Weise verwenden, aber ich würde mich besser fühlen, wenn ich wüsste, warum dies geschieht, bevor ich mit Redux fortfahre. Ich benutze Webpack mit Babel-Loadern zum Kompilieren.

Mein Code:

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

Prost.

besudeln
quelle
Ich hatte dieses Problem und dies half mir, es zu lösen
Alex W

Antworten:

248

Wenn Sie mapDispatchToPropsohne eine mapStateToPropsnur nullfür das erste Argument verwenden möchten .

export default connect(null, mapDispatchToProps)(Start)

Inostia
quelle
4
Das habe ich gesucht. Jetzt weiß ich, ob ich nur einige Aktionen auslösen möchte.
Kaiser Krauser
Genau das habe ich gesucht. Danke für die perfekte Lösung. Was ist, wenn wir mapDispatchToProps in keiner unserer Komponenten verwenden müssen? Ist es die gleiche Art und Weise, wie wir mit diesem Szenario umgehen müssen?
Arun Ramachandran
1
Wenn Sie nicht brauchen mapDispatchToProps, fügen Sie dieses Argument einfach nicht hinzu zu connect:connect(mapStateToProps)(MyComponent)
Inostia
107

Ihnen fehlt nur das erste Argument connect, nämlich die mapStateToPropsMethode. Auszug aus der Redux todo App:

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)
Brandon
quelle
3
Ist diese Methode obligatorisch? Diese Methode fängt nur den Status ab, was ist, wenn wir diese Methode nicht benötigen?
Muneem Habib
6
@ MunemHabib siehe inostias Antwort, wie man diese Methode nicht liefert, wenn man sie nicht braucht
Brandon
21

Verwenden

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

anstatt

const StartContainer = connect(mapDispatchToProps)(Start)
Ann
quelle
5

Ich habe es gelöst, indem ich die Argumente ausgetauscht habe, die ich verwendet habe

export default connect(mapDispatchToProps, mapStateToProps)(Checkbox)

was falsch ist. Das mapStateToPropsmuss das erste Argument sein:

export default connect(mapStateToProps, mapDispatchToProps)(Checkbox)

Es klingt jetzt offensichtlich, könnte aber jemandem helfen.

Amit Mittal
quelle
3

Ich brauchte ein Beispiel mit, React.Componentalso poste ich es:

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);
Amio.io
quelle
3

Problem

Hier sind einige Dinge zu beachten, um das Verhalten der verbundenen Komponente in Ihrem Code zu verstehen:

Die Arität der connectDinge:connect(mapStateToProps, mapDispatchToProps)

React-Redux-Aufrufe connectmit dem ersten mapStateToPropsund dem zweiten Argument mapDispatchToProps.

Daher mapDispatchToPropsbehandelt React-Redux das , obwohl Sie es bestanden haben , tatsächlich als mapStatedas erste Argument. Sie erhalten weiterhin die injizierte onSubmitFunktion in Ihrer Komponente, da die Rückgabe von mapStatemit den Requisiten Ihrer Komponente zusammengeführt wird. Aber so geht das nichtmapDispatch soll man nicht spritzen.

Sie können mapDispatchohne Definition verwenden mapState. Übergeben Sie nullanstelle von mapStateund Ihre Komponente unterliegt keinen Speicheränderungen.

Verbundene Komponente empfängt dispatchstandardmäßig, wenn Nein angegeben mapDispatchist

Außerdem erhält Ihre Komponente, dispatchweil sie nullfür ihre zweite Position für empfangen hat mapDispatch. Wenn Sie ordnungsgemäß übergeben mapDispatch, wird Ihre Komponente nicht empfangen dispatch.

Gang und gäbe sein

Das Obige beantwortet, warum sich die Komponente so verhalten hat. Es ist jedoch üblich, dass Sie Ihren Aktionsersteller einfach mit mapStateToPropsder Objektkürzel übergeben. Und nennen Sie das innerhalb Ihrer Komponente. onSubmitDas heißt:

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)
wgao19
quelle
0

Wenn Sie nicht mapDispatchToPropsals zweites Argument angeben, wie folgt:

export default connect(mapStateToProps)(Checkbox)

Dann erhalten Sie automatisch den Versand zu den Requisiten der Komponente, sodass Sie einfach:

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

ohne mapDispatchToProps

Serge Nikolaev
quelle
0

Ich benutze so .. sein leicht zu verstehendes erstes Argument ist mapStateToProps und das zweite Argument ist mapDispatchToProps am Ende verbinden mit Funktion / Klasse.

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);
Abdul Moiz
quelle
Wenn Sie kein erstes Argument haben, übergeben Sie einfach null / undefiniert und dann das zweite Argument.
Abdul Moiz
0

Manchmal tritt dieser Fehler auch auf, wenn Sie die Reihenfolge der Komponentenfunktionen ändern, während Sie die Verbindung übergeben.

Falsche Reihenfolge:

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

Korrekten Reihenfolge:

export default connect(mapStateToProps,mapDispatchToProps)(TodoList);
Codiee
quelle
0

Eine Falle, in die einige möglicherweise eintreten, wird von dieser Frage abgedeckt, aber in den Antworten nicht behandelt, da sie sich in der Codestruktur geringfügig unterscheidet, aber genau denselben Fehler zurückgibt.

Dieser Fehler tritt auf, wenn bindActionCreatorsdie dispatchFunktion verwendet und nicht übergeben wird

Fehlercode

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)

Fester Code

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)

Die Funktion dispatchfehlte im Fehlercode

ich bin Batman
quelle
0

Die React-Redux-Funktion 'connect' akzeptiert zwei Argumente: erstens mapStateToProps und zweitens mapDispatchToProps.

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

Wenn wir den Status nicht aus Redux abrufen möchten, setzen wir null anstelle von mapStateToProps.

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

Sachin Metkari
quelle