2016-02-16 19 views
40

Jestem początkującym skryptem javascript/redux/react budującym małą aplikację z redux, re- akcji-redux, &. Z jakiegoś powodu przy korzystaniu z funkcji mapDispatchToProps w połączeniu z connect (binding-redux binding) otrzymuję TypeError wskazujący, że wysyłka nie jest funkcją, gdy próbuję wykonać wynikowy prop. Kiedy jednak nazywam wysyłkę jako rekwizyt (zobacz funkcję setAddr w podanym kodzie), działa.'dispatch' nie jest funkcją, gdy argument do mapToDispatchToProps() w Redux

Jestem ciekawy, dlaczego tak jest, w przykładowej aplikacji TODO w dokumentacji redux metoda mapDispatchToProps jest ustawiona w ten sam sposób. Kiedy console.log (dispatch) wewnątrz funkcji, oznacza to, że dispatch jest obiektem typu. Mogłabym nadal używać wysyłki w ten sposób, ale czułbym się lepiej wiedząc, dlaczego tak się dzieje, zanim przejdę dalej z redux. Do kompilacji używam pakietu internetowego z programami babel-loader.

mój kod:

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 

Cheers.

Odpowiedz

68

Po prostu brakuje pierwszego argumentu na connect, który jest metodą mapStateToProps. Wyciąg z todo aplikacji Redux:

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) 
+2

Czy korzystanie z tej metody jest obowiązkowe? Ta metoda po prostu łapie, co jeśli nie potrzebujemy tej metody? –

+2

@MuneemHabib zobacz odpowiedź od inostii na pytanie, jak nie dostarczyć tej metody, jeśli jej nie potrzebujesz – Brandon

3

Potrzebowałem przykład używając React.Component więc jestem delegowania go:

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); 
60

Jeśli chcesz użyć mapDispatchToProps bez mapStateToProps wystarczy użyć null dla pierwszego argumentu.

export default connect(null, mapDispatchToProps)(Start)

+3

Tego właśnie szukałem. Teraz wiem, czy chcę tylko wysłać kilka akcji. –

5

Zastosowanie

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

zamiast

const StartContainer = connect(mapDispatchToProps)(Start) 
1

Rozwiązałem go poprzez wymianę argumentów, używałem

export default connect(mapDispatchToProps, mapStateToProps)(Checkbox) 

co jest źle. mapStateToProps musi być pierwszy argument:

export default connect(mapStateToProps, mapDispatchToProps)(Checkbox) 

Brzmi to oczywiste teraz, ale może komuś pomóc.

0

Jeśli nie zapewniają mapDispatchToProps jako drugi argument, jak to:

export default connect(mapStateToProps)(Checkbox) 

wtedy są automatycznie otrzymujesz wysyłkę do rekwizytów komponentu, więc można po prostu:

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

bez mapDispatchToProps