Redux'ta mapToDispatchToProps () argümanında 'dispatch' bir işlev değildir


124

Redux, react-redux ve react ile küçük bir uygulama geliştiren bir javascript / redux / react acemisiyim. Bazı nedenlerden dolayı mapDispatchToProps işlevini connect (react-redux bağlama) ile birlikte kullanırken ortaya çıkan prop çalıştırmaya çalıştığımda gönderimin bir işlev olmadığını belirten bir TypeError alıyorum. Ancak dağıtımı bir destek olarak çağırdığımda (verilen kodda setAddr işlevine bakın) çalışıyor.

Bunun nedenini merak ediyorum, redux belgelerindeki TODO uygulamasında mapDispatchToProps yönteminin aynı şekilde ayarlandığını. İşlevin içinde console.log (dispatch) kullandığımda, dispatch'in tür nesnesi olduğunu söylüyor. Dispatch'i bu şekilde kullanmaya devam edebilirdim, ancak redux ile devam etmeden önce bunun neden olduğunu bildiğimde daha iyi hissederim. Derlemek için babel yükleyicilerle webpack kullanıyorum.

Kodum:

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

Şerefe.


Ben bu sorunu başlamıştı ve bu beni bunu çözmek yardımcı
Alex W

Yanıtlar:


249

Kullanmak isterseniz mapDispatchToPropsbir olmadan mapStateToPropssadece kullanım nullbirinci argüman.

export default connect(null, mapDispatchToProps)(Start)


4
Bu benim aradığım şey. Şimdi sadece bazı eylemler göndermek isteyip istemediğimi biliyorum.
İmparator Krauser

Bu tam olarak aradığım bir şey. Mükemmel çözüm için teşekkürler. Herhangi bir bileşenimizde mapDispatchToProps kullanmak zorunda değilsek ne olur? Bu senaryoyu halletmemiz gereken yol aynı mı?
Arun Ramachandran

1
İhtiyacınız yoksa mapDispatchToProps, şu argümanı eklemeyin connect:connect(mapStateToProps)(MyComponent)
inostia

107

Sadece yöntem connectolan ilk argümanı kaçırıyorsunuz mapStateToProps. Redux todo uygulamasından alıntı:

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
bu yöntemi kullanmak zorunlu mu? Bu yöntem sadece durumu yakalarsa ya bu yönteme ihtiyacımız yoksa?
Muneem Habib

6
@MuneemHabib, ihtiyacınız yoksa bu yöntemi nasıl sağlamayacağınıza dair inostia'nın cevabını görün
Brandon

21

kullanım

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

onun yerine

const StartContainer = connect(mapDispatchToProps)(Start)

6

Argümanları değiştirerek çözdüm, kullanıyordum

export default connect(mapDispatchToProps, mapStateToProps)(Checkbox)

hangisi yanlış. mapStateToPropsİlk argüman olmak zorunda:

export default connect(mapStateToProps, mapDispatchToProps)(Checkbox)

Şimdi apaçık geliyor ama birine yardımcı olabilir.


3

Kullanarak bir örneğe ihtiyacım vardı, React.Componentbu yüzden onu gönderiyorum:

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

Konu

Kodunuzdaki bağlı bileşenin davranışını anlamak için dikkat etmeniz gereken birkaç nokta:

connectKonuların Arity'si :connect(mapStateToProps, mapDispatchToProps)

React-Redux connectilk argüman mapStateToPropsve ikinci argüman ile çağrı yapar mapDispatchToProps.

Bu nedenle, geçmişte kalmanıza rağmen mapDispatchToProps başınıza , React-Redux aslında mapStatebunu ilk argüman olduğu için ele alıyor . onSubmitBileşeninize hala enjekte edilen işlevi alırsınız, çünkü dönüşü mapStatebileşeninizin props ile birleştirilir. Ama bu nasıl mapDispatchenjekte edilmesi gerektiği değil .

mapDispatchTanımlamadan kullanabilirsinizmapState . Aktarın nullyerine mapStateve bileşen mağaza değişikliklerine tabi olmaz.

Bağlı Bileşen Alır dispatchmapDispatch Sağlanmadığında Varsayılan Olarak Alınır

Ayrıca, bileşeniniz aldığı dispatchiçin alırnull ikinci konumu için içinmapDispatch . Düzgün bir şekilde geçerseniz mapDispatch, bileşeniniz almayacaktır dispatch.

Yaygın uygulama

Yukarıdaki, bileşenin neden bu şekilde davrandığını yanıtlamaktadır. Yine de, eylem yaratıcınıza mapStateToProps'nın nesne stenosunu kullanarak geçmeniz yaygın bir uygulamadır . Ve buna bileşeninizin içinde onSubmitO diyebilirsiniz :

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

Ne zaman vermeyin mapDispatchToPropsböyle bir ikinci argüman olarak:

export default connect(mapStateToProps)(Checkbox)

o zaman otomatik olarak bileşenin props'larına dağıtımı alıyorsunuz, böylece şunları yapabilirsiniz:

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

mapDispatchToProps olmadan


0

Ben böyle kullanıyorum .. Anlaşılması kolay ilk argüman mapStateToProps ve ikinci argüman ise mapDispatchToProps son connect function / class.

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

Eğer ilk argümanınız yoksa, sadece boş / tanımsız ve sonra ikinci argümanı
iletin

0

Bazen bu hata, bağlantıya geçerken Bileşen İşlevinin sırasını değiştirdiğinizde de ortaya çıkar.

Yanlış Sipariş:

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

Doğru sipariş:

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

0

Bazılarının bu sorunun kapsadığı ancak kod yapısında biraz farklı olduğu, ancak tam olarak aynı hatayı döndürdüğü için yanıtlarda ele alınmayan bir tuzak olabilir.

Bu hata bindActionCreators, dispatchişlevi kullanırken ve geçmediğinde ortaya çıkar

Hata kodu

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)

Sabit Kod

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)

dispatchHata kodunda işlev eksikti


0

React-redux 'connect' işlevi, ilk olarak mapStateToProps olan iki argümanı kabul eder ve ikincisi, aşağıdaki mapDispatchToProps kontrolüdür.

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

Redux'dan state almak istemiyorsak, mapStateToProps yerine null ayarlıyoruz.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.