2017-02-13 5 views
0

Ich versuche, meine erste Verbindung zwischen einer React-Komponente zu Redux zu erstellen, um Daten von meiner Knoten-API zu sammeln.Wie verbinde ich eine ReactJS-Komponente richtig mit Redux mit react-redux?

Dies ist eine einfache Komponente für jetzt, aber es wird in der Zukunft wachsen und wird Unterkomponenten ableiten, die mir erlauben, eine vollständige Benutzer CRUD-Schnittstelle (Liste, bearbeiten, löschen, anzeigen, etc.) zu erstellen. In diesem Sinne muss ich die Aktionsfunktionen mit dem Objekt this.props verbinden, damit es von den untergeordneten Komponenten geerbt werden kann.

Hier ist mein Code:

Component UserGrid - Ein Raster-Tabellendaten, die Benutzer Informationen

lädt
import React from 'react'; 
import { bindActionCreators } from 'redux'; 
import { connect } from 'react-redux'; 
import * as userActions from '../../actions/userActions'; 

class UserGrid extends React.Component { 
    componentWillMount() { 
    this.props.fetchUsers(); 
    } 

    render() { 
    const mappedUsers = users.map(user => <li>{user.email}</li>); 
    return (
      <div> 
       <ul>{mappedUsers}</ul> 
      </div> 
     ); 
    } 
} 

function mapStateToProps(state) { 
    return { 
     users: state.users 
    } 
} 

export default connect(
    mapStateToProps, 
    bindActionCreators(userActions, dispatch) 
)(UserGrid); 

Mein userAction, dass effektiv Benutzer laden von einem AJAX-Aufruf:

import axios from "axios"; 

export function fetchUsers() { 
    return function(dispatch) { 
    axios.get("/api/users") 
     .then((response) => { 
     dispatch({type: "FETCH_USERS_FULFILLED", payload: response.data}); 
     }) 
     .catch((err) => { 
     dispatch({type: "FETCH_USERS_REJECTED", payload: err}); 
     }) 
    } 
} 

Mit diesem Code bekomme ich Folgendes Fehler:

Uncaught ReferenceError: dispatch is not defined 
    at Object.<anonymous> (bundle.js:37984) 
    at __webpack_require__ (bundle.js:556) 
    at fn (bundle.js:87) 
    at Object.<anonymous> (bundle.js:37711) 
    at __webpack_require__ (bundle.js:556) 
    at fn (bundle.js:87) 
    at Object.<anonymous> (bundle.js:8466) 
    at __webpack_require__ (bundle.js:556) 
    at fn (bundle.js:87) 
    at Object.<anonymous> (bundle.js:588) 
(anonymous) @ bundle.js:37984 
__webpack_require__ @ bundle.js:556 
fn @ bundle.js:87 
(anonymous) @ bundle.js:37711 
__webpack_require__ @ bundle.js:556 
fn @ bundle.js:87 
(anonymous) @ bundle.js:8466 
__webpack_require__ @ bundle.js:556 
fn @ bundle.js:87 
(anonymous) @ bundle.js:588 
__webpack_require__ @ bundle.js:556 
(anonymous) @ bundle.js:579 
(anonymous) @ bundle.js:582 

Was ist der richtige Weg, um meine Komponente mit den Redux-Diensten zu verbinden?

+0

Sie passieren 'dispatch' als Argument an' bindActionCreators' aber es ist nicht überall definiert. –

Antwort

1

In der Komponente möchten Sie die Funktion mapDispatchToProps definieren müssen verbinden. Diese Funktion übernimmt den Versand als Parameter und erhält diesen Parameter, wenn connect die Funktion aufruft.

Hier ist ein Beispiel Code aus einem meiner letzten Projekte gezogen.

function mapDispatchToProps(dispatch) { 
     return { 
      adminActions: bindActionCreators(adminOrdersActions, dispatch), 
      schoolActions: bindActionCreators(schoolOrdersListActions, dispatch), 
      userActions: bindActionCreators(userActions, dispatch) 
     }; 
    } 

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

Jetzt ist der Versand definiert.

BEARBEITEN: Um dies zu verdeutlichen, erhalten Sie jetzt Zugriff auf Ihre Aktionen mit der folgenden Syntax. this.props.actions.yourAction, oder was auch immer Sie die Aktionen in der mapDispatchToProps genannt haben.

Dies ist der Code mit meinen Änderungen:

import React from 'react'; 
import { bindActionCreators } from 'redux'; 
import { connect } from 'react-redux'; 

import * as userActions from '../../actions/userActions'; 

class UserGrid extends React.Component { 

    componentWillMount() { 
    console.log(JSON.stringify(this.props)); 

    //this.props.fetchUsers(); 
    this.props.actions.fetchUsers(); 
    } 

    render() { 

    const mappedUsers = users.map(user => <li>{user.email}</li>) 

    return (
      <div> 
      <ul>{mappedUsers}</ul> 
      </div> 
     ) 
    } 
} 

function mapStateToProps(state) { 
    return { 
     users: state.users 
    } 
} 

function mapDispatchToProps(dispatch) { 
    // this function will now give you access to all your useractions by simply calling this.props.actions. 
    //if the key of this object would not be actions, but rather foobar, you will get your actions by 
    // calling this.props.foobar 
    return { 
     actions: bindActionCreators(userActions, dispatch) 
    } 
} 

export default connect(
    mapStateToProps, 
    mapDispatchToProps 
)(UserGrid); 
+0

Dadurch habe ich den folgenden Fehler erhalten: 'bindActionCreators erwartet ein Objekt oder eine Funktion, stattdessen undefined erhalten. Hast du "import ActionCreators from" anstelle von "import * als ActionCreators from" geschrieben? ' – Mendes

+0

import * so wie es geht' import * als schoolOrdersListActions von '../actions/schoolOrdersListActions'; ' –

+0

nun ein weiterer Fehler:' Uncaught Typeerror: this.props.fetchUsers ist keine Funktion bei UserGrid.componentWillMount (bundle.js: 37951) ' – Mendes

1

Ich glaube nicht, dass Sie bindActionCreators hier verwenden möchten. Hier ist, was the docs sagen (Hervorhebung von mir):

Normally you should just call dispatch directly on your Store instance. If you use Redux with React, react-redux will provide you with the dispatch function so you can call it directly, too.

The only use case for bindActionCreators is when you want to pass some action creators down to a component that isn't aware of Redux, and you don't want to pass dispatch or the Redux store to it.

Da das ist nicht das, was du tust, du stattdessen dispatch direkt anrufen sollte. Mit reagieren-redux wird connect es in Ihre Requisiten injizieren, so können Sie dies nur tun:

componentWillMount() { 
    this.props.dispatch(fetchUsers()); 
} 
+0

Ja, ich bin mir dessen bewusst, aber ich möchte 'this.props.fetchUsers()' anstelle von 'this.props.dispatch (fetchUsers())' verwenden.'UserGrid' ist eine jetzt einfache Komponente, wird aber wachsen und Unterkomponenten haben, die die Versandfunktionen direkt auf ihren Requisiten verwenden müssen. – Mendes

+0

Ihre Frage drückt das nicht wirklich aus. Können Sie es bearbeiten, um Ihren Anwendungsfall deutlicher zu demonstrieren? –

+0

Sicher, in der ursprünglichen Post getan. – Mendes

1

Als Jordan said würde ich nicht bindActionCreators verwenden.

Ihre Komponente sollte in etwa so aussehen:

import React from 'react'; 
import { connect } from 'react-redux'; 

import myAction from './my-action'; 

class MyComponent extends React.Component { 

    componentDidMount() { 
     this.props.myAction(); 
    } 

    render() { 
     return "Hi!" 
    } 

} 

const mapStateToProps = (state) => ({ 
    myState: state.myState 
}); 

const mapDispatchToProps = (dispatch) => ({ 
    myAction:() => dispatch(myAction()) 
}); 

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