'dispatch' bukanlah fungsi saat argumen ke mapToDispatchToProps () di Redux


124

Saya seorang pemula javascript / redux / react membangun aplikasi kecil dengan redux, react-redux, & react. Untuk beberapa alasan saat menggunakan fungsi mapDispatchToProps bersama-sama dengan connect (react-redux binding) saya menerima TypeError yang menunjukkan bahwa pengiriman bukan fungsi ketika saya mencoba menjalankan prop yang dihasilkan. Namun, ketika saya memanggil dispatch sebagai prop (lihat fungsi setAddr di kode yang disediakan) itu berfungsi.

Saya ingin tahu mengapa ini terjadi, dalam contoh aplikasi TODO di redux, metode mapDispatchToProps disiapkan dengan cara yang sama. Ketika saya console.log (dispatch) di dalam fungsi itu dikatakan dispatch adalah tipe objek. Saya dapat terus menggunakan pengiriman dengan cara ini tetapi saya akan merasa lebih baik mengetahui mengapa ini terjadi sebelum saya melanjutkan lebih jauh dengan redux. Saya menggunakan webpack dengan babel-loader untuk dikompilasi.

Kode Saya:

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

Bersulang.


Saya mengalami masalah ini dan ini membantu saya mengatasinya
Alex W

Jawaban:


249

Jika Anda ingin menggunakan mapDispatchToPropstanpa mapStateToPropsmenggunakan nulluntuk argumen pertama.

export default connect(null, mapDispatchToProps)(Start)


4
Inilah yang selama ini saya cari. Sekarang saya tahu apakah saya hanya ingin mengirimkan beberapa tindakan.
Kaisar Krauser

Ini persis seperti yang saya cari. Terima kasih atas solusi yang tepat. Bagaimana jika kita tidak harus menggunakan mapDispatchToProps di salah satu komponen kita? Apakah cara yang sama kita harus menangani skenario itu?
Arun Ramachandran

1
Jika Anda tidak membutuhkannya mapDispatchToProps, jangan tambahkan argumen itu ke connect:connect(mapStateToProps)(MyComponent)
inostia

107

Anda baru saja kehilangan argumen pertama connect, yaitu mapStateToPropsmetode. Kutipan dari aplikasi rencana 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)

3
apakah wajib menggunakan metode ini? Metode ini hanya menangkap keadaan bagaimana jika kita tidak membutuhkan metode ini?
Muneem Habib

6
@MuneemHabib lihat jawaban inostia untuk bagaimana tidak menyediakan metode ini jika Anda tidak membutuhkannya
Brandon

21

Menggunakan

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

dari pada

const StartContainer = connect(mapDispatchToProps)(Start)

6

Saya menyelesaikannya dengan menukar argumen, yang saya gunakan

export default connect(mapDispatchToProps, mapStateToProps)(Checkbox)

mana yang salah. The mapStateToPropsharus menjadi argumen pertama:

export default connect(mapStateToProps, mapDispatchToProps)(Checkbox)

Kedengarannya sudah jelas sekarang, tapi mungkin bisa membantu seseorang.


3

Saya membutuhkan contoh yang digunakan React.Componentjadi saya mempostingnya:

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

Isu

Berikut ini beberapa hal yang perlu diperhatikan untuk memahami perilaku komponen yang terhubung dalam kode Anda:

Arity of connectMatters:connect(mapStateToProps, mapDispatchToProps)

React-Redux memanggil connectdengan argumen pertama mapStateToProps, dan argumen kedua mapDispatchToProps.

Oleh karena itu, meskipun Anda telah mengirimkannya mapDispatchToProps, React-Redux pada kenyataannya memperlakukan itu mapStatekarena ini adalah argumen pertama. Anda masih mendapatkan onSubmitfungsi yang diinjeksi di komponen Anda karena pengembalian dari mapStatedigabungkan ke dalam props komponen Anda. Tapi itu belum seberapamapDispatch disuntikkan.

Anda dapat menggunakan mapDispatchtanpa menentukan mapState. Berikan nullmenggantikan mapStatedan komponen Anda tidak akan mengalami perubahan penyimpanan.

Komponen Terhubung Diterima dispatchsecara Default, Ketika Tidak mapDispatchAda

Juga, komponen Anda menerima dispatchkarena menerima nullposisi kedua untuk mapDispatch. Jika Anda meneruskan dengan benar mapDispatch, komponen Anda tidak akan menerima dispatch.

Praktek Umum

Jawaban di atas mengapa komponen berperilaku seperti itu. Meskipun, ini adalah praktik umum bahwa Anda hanya meneruskan pembuat tindakan Anda menggunakan mapStateToPropssingkatan objek. Dan sebut itu di dalam komponen Anda onSubmityaitu:

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

Jika Anda tidak memberikan mapDispatchToPropssebagai argumen kedua, seperti ini:

export default connect(mapStateToProps)(Checkbox)

maka Anda secara otomatis mendapatkan pengiriman ke props komponen, jadi Anda dapat:

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

tanpa mapDispatchToProps


0

saya menggunakan seperti ini .. yang mudah untuk memahami argumen pertama adalah mapStateToProps dan argumen kedua adalah mapDispatchToProps pada akhirnya terhubung dengan fungsi / kelas.

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

jika Anda tidak memiliki argumen pertama maka berikan saja null / undefined dan kemudian argumen kedua ..
Abdul Moiz

0

Kadang-kadang kesalahan ini juga terjadi ketika Anda mengubah urutan Fungsi Komponen saat lewat untuk menyambung.

Pesanan Salah:

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

Pesanan yang Benar:

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

0

Jebakan beberapa mungkin masuk yang tercakup oleh pertanyaan ini tetapi tidak dibahas dalam jawaban karena sedikit berbeda dalam struktur kode tetapi mengembalikan kesalahan yang sama persis.

Kesalahan ini terjadi saat menggunakan bindActionCreatorsdan tidak meneruskan dispatchfungsi

Kode Kesalahan

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)

Kode Tetap

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)

Fungsi dispatchtidak ada di kode Kesalahan


0

Fungsi 'connect' React-redux menerima dua argumen pertama adalah mapStateToProps dan kedua adalah cek mapDispatchToProps di bawah ex.

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

Jika kami tidak ingin mengambil status dari redux maka kami menetapkan null alih-alih mapStateToProps.

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.