'Dispatch' không phải là một hàm khi đối số với mapToDispatchToProps () trong Redux


124

Tôi là người mới bắt đầu sử dụng javascript / redux / react đang xây dựng một ứng dụng nhỏ với redux, react-redux và react. Vì một số lý do khi sử dụng hàm mapDispatchToProps song song với kết nối (liên kết phản ứng-redux), tôi nhận được Lỗi TypeError cho biết rằng điều phối không phải là một chức năng khi tôi cố gắng thực hiện hỗ trợ kết quả. Tuy nhiên, khi tôi gọi điều phối là một công cụ hỗ trợ (xem hàm setAddr trong mã được cung cấp), nó hoạt động.

Tôi tò mò không biết tại sao lại như vậy, trong ứng dụng TODO ví dụ trong redux tài liệu, phương thức mapDispatchToProps được thiết lập theo cùng một cách. Khi tôi console.log (chuyển văn bản) bên trong hàm, nó nói rằng văn bản là đối tượng loại. Tôi có thể tiếp tục sử dụng công văn theo cách này nhưng tôi sẽ cảm thấy tốt hơn khi biết tại sao điều này lại xảy ra trước khi tôi tiếp tục thêm nữa với redux. Tôi đang sử dụng webpack với bộ tải babel để biên dịch.

Mã của tôi:

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

Chúc mừng.


Tôi đang gặp sự cố này và điều này đã giúp tôi giải quyết nó
Alex W

Câu trả lời:


249

Nếu bạn muốn sử dụng mapDispatchToPropsmà không có mapStateToPropschỉ sử dụng nullcho đối số đầu tiên.

export default connect(null, mapDispatchToProps)(Start)


4
Đây là những gì tôi đã tìm kiếm. Bây giờ tôi biết nếu tôi chỉ muốn gửi một số hành động.
Emperor Krauser,

Đây chính xác là thứ mà tôi đang tìm kiếm. Cảm ơn vì giải pháp hoàn hảo. Điều gì sẽ xảy ra nếu chúng ta không phải sử dụng mapDispatchToProps trong bất kỳ thành phần nào của mình? Nó có giống cách chúng ta phải xử lý tình huống đó không?
Arun Ramachandran

1
Nếu bạn không cần mapDispatchToProps, chỉ cần không thêm lập luận rằng để connect:connect(mapStateToProps)(MyComponent)
inostia

107

Bạn chỉ thiếu đối số đầu tiên connect, đó là mapStateToPropsphương thức. Trích từ ứng dụng todo 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
có bắt buộc phải sử dụng phương pháp này không? Phương thức này chỉ bắt trạng thái nếu chúng ta không cần phương thức này thì sao?
Muneem Habib

6
@MuneemHabib xem câu trả lời của inostia về cách không cung cấp phương pháp này nếu bạn không cần
Brandon

21

Sử dụng

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

thay vì

const StartContainer = connect(mapDispatchToProps)(Start)

6

Tôi đã giải quyết nó bằng cách trao đổi các đối số, tôi đang sử dụng

export default connect(mapDispatchToProps, mapStateToProps)(Checkbox)

sai chỗ nào. Các mapStateToPropsđã được các đối số đầu tiên:

export default connect(mapStateToProps, mapDispatchToProps)(Checkbox)

Bây giờ nghe có vẻ hiển nhiên, nhưng có thể giúp ích cho ai đó.


3

Tôi cần một ví dụ bằng cách sử dụng React.Componentvì vậy tôi đăng nó:

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

Vấn đề

Dưới đây là một số điều cần lưu ý để hiểu hành vi của thành phần được kết nối trong mã của bạn:

Sự hiếm có của các connectvấn đề:connect(mapStateToProps, mapDispatchToProps)

React-Redux gọi connectvới đối số đầu tiên mapStateToPropsvà đối số thứ hai mapDispatchToProps.

Do đó, mặc dù bạn đã vượt qua trong của mình mapDispatchToProps, React-Redux trên thực tế xử lý điều đó mapStatevì nó là đối số đầu tiên. Bạn vẫn nhận được onSubmithàm được chèn vào trong thành phần của mình vì giá trị trả về mapStateđược hợp nhất vào đạo cụ của thành phần của bạn. Nhưng đó không phải là cách mapDispatchđược cho là tiêm.

Bạn có thể sử dụng mapDispatchmà không cần xác định mapState. Chuyển nullvào chỗ mapStatevà thành phần của bạn sẽ không bị thay đổi trong cửa hàng.

Thành phần được kết nối nhận dispatchtheo mặc định, khi không được mapDispatchcung cấp

Ngoài ra, thành phần của bạn nhận được dispatchvì nó nhận được nullvị trí thứ hai cho mapDispatch. Nếu bạn nhập đúng cách mapDispatch, thành phần của bạn sẽ không nhận được dispatch.

Thực tế phổ biến

Các câu trả lời ở trên tại sao thành phần hoạt động theo cách đó. Mặc dù, thực tế phổ biến là bạn chỉ cần chuyển cho trình tạo hành động của mình bằng cách sử dụng mapStateToPropstốc ký đối tượng của. Và gọi điều đó trong thành phần của bạn onSubmitĐó là:

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

Khi bạn không cung cấp mapDispatchToPropsnhư một đối số thứ hai, như sau:

export default connect(mapStateToProps)(Checkbox)

thì bạn sẽ tự động nhận được điều phối đến các đạo cụ của thành phần, vì vậy bạn có thể chỉ cần:

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

mà không có bất kỳ mapDispatchToProps nào


0

tôi đang sử dụng như thế này .. đối số đầu tiên dễ hiểu của nó là mapStateToProps và đối số thứ hai là mapDispatchToProps cuối cùng kết nối với hàm / lớp.

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

Nếu bạn không có đối số đầu tiên sau đó chỉ cần vượt qua null / undefined và tranh luận sau đó thứ hai ..
Abdul Moiz

0

Đôi khi lỗi này cũng xảy ra khi bạn thay đổi thứ tự của Hàm thành phần trong khi truyền để kết nối.

Thứ tự không chính xác:

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

Đúng thứ tự:

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

0

Một số khó khăn có thể mắc phải trong câu hỏi này nhưng không được giải quyết trong các câu trả lời vì nó hơi khác trong cấu trúc mã nhưng trả về cùng một lỗi chính xác.

Lỗi này xảy ra khi sử dụng bindActionCreatorsvà không chuyển dispatchhàm

Mã lỗi

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)

Mã cố định

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)

Chức năng dispatchbị thiếu trong mã lỗi


0

Hàm React-redux 'connect' chấp nhận hai đối số đầu tiên là mapStateToProps và thứ hai là mapDispatchToProps kiểm tra bên dưới ví dụ:

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

Nếu chúng ta không muốn truy xuất trạng thái từ redux thì chúng ta đặt null thay vì mapStateToProps.

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.