如何使用react-redux将ReactJS组件正确连接到Redux?

时间:2017-02-13 16:48:45

标签: javascript reactjs react-redux

我正在尝试构建React组件与Redux之间的第一个连接,以从我的节点API收集数据。

现在这是一个简单的组件,但它将来会增长,并将派生子组件,这将允许我构建一个完整的用户CRUD界面(列表,编辑,删除,查看等)。从这个意义上说,我需要将动作函数连接到对象this.props,以便它可以由子组件继承。

这是我的代码:

组件UserGrid - 将加载用户信息的表数据网格

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

我的userAction,可以有效地从AJAX通话中加载用户:

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

使用此代码我收到以下错误:

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

将我的组件连接到创建的Redux服务的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

我不认为你想在这里使用bindActionCreators。这是the docs所说的(强调我的):

  

通常,您应该直接在dispatch个实例上致电Store。如果你将Redux与React一起使用,react-redux将为你提供dispatch功能,你也可以直接调用它。

     

bindActionCreators的唯一用例是,当您想要将某些动作创建者传递给一个不了解Redux 的组件时,您就不会这样做想要将dispatch或Redux商店传递给它。

由于这不是您正在做的事情,您应该直接致电dispatch。使用react-redux,connect会将它注入到你的道具中,所以你可以这样做:

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

答案 1 :(得分:1)

在您要连接的组件中,您需要定义函数mapDispatchToProps。此函数将调度作为参数,并在connect调用函数时接收此参数。

以下是我最近的一个项目中的一些示例代码。

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

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

现在定义了调度。

编辑:为了澄清,这样做现在可以使用以下语法访问您的操作。 this.props.actions.yourAction,或者您在mapDispatchToProps中所谓的操作。

这是我的更改代码:

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

答案 2 :(得分:1)

作为Jordan said,我不会使用bindActionCreators

您的组件应如下所示:

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