开发者问题收集

Redux Action 尚未被调度

2019-05-24
85

我正在开发一个 react - redux 应用程序。现在我遇到了一个调度操作的问题。以下代码无法调度 generateReport 操作。

import React, { Component } from "react";
import { Button, Icon } from "semantic-ui-react";
import { connect } from "react-redux";
import { submit, getFormValues, isValid } from "redux-form";
import { generateReport } from "../actions/generateActions";
import { Link } from "react-router-dom";

const docsButtonStyle = {
  position: "fixed",
  marginBottom: "0.5em",
  marginLeft: "0.1em",
  bottom: 0,
  left: 0,
  animation: "back-to-docs 1.5s ease-in-out infinite",
  zIndex: 6
};

class ButtonGroup extends Component {
  generate = () => {
    this.props.generateReport(this.props.values);
  };     

  render() {
    return (
      <div style={docsButtonStyle}>
        <Button.Group vertical>              
          <Button animated="fade" color="teal" onClick={this.generate}>
            <Button.Content hidden>Generate</Button.Content>
            <Button.Content visible>
              <Icon name="chart bar" size="large" />
            </Button.Content>
          </Button>
        </Button.Group>
      </div>
    );
  }
}

const mapStateToProps = state => ({
  values: getFormValues("privateForm")(state),
  valid: isValid("privateForm")(state)
});

const mapDispatchToProps = dispatch => ({
  generateReport,
  remoteSubmit: () => {
    dispatch(submit("privateForm"));
  }
});

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

generateActions.js

export const generateReport = values => async dispatch => {
  console.log("test");
  try {
    dispatch(generateReportBegin());
    const response = await axios.post(`${ROOT_URL}/submit`, values);
    dispatch(generateReportSuccess());
  } catch (error) {

  }
};

如果我将 connect 函数更改为

export default connect(
  mapStateToProps,
  {generateReport}
)(ButtonGroup);

它可以工作。有人能告诉我为什么它在第一种情况下不起作用吗?谢谢。

1个回答

发生这种情况是因为 connect 函数的行为不同 取决于传递给 mapDispatchToProps 的参数

  1. 如果您传递函数,它将以 dispatch 作为第一个参数进行调用,并且生成的对象将合并到 props 。在这种情况下,假定您在提供的函数中为每个操作准备 dispatch 调用。

    在代码中

    const mapDispatchToProps = dispatch => ({
    generateReport,
    remoteSubmit: () => {
    dispatch(submit("privateForm"));
    }
    });
    

    mapDispatchToProps 将使用 dispatch 作为参数进行调用,并生成具有 2 个函数的对象。 remoteSubmit 应能正常工作,因为它已绑定到 dispatch 。但 generateReport 只是一些按原样传递的外部函数。因此,在对 this.props.generateReport 的任何调用中,将仅返回以 dispatch 作为参数的函数。 Redux 认为您已在 mapDispatchToProps 中准备好调度所需的一切,因此它什么也不做。

  2. 如果您将对象作为 mapDispatchToProps 传递(您在第二个示例中执行的操作), connect 将为您调用 bindActionCreators 并将 generateReport 包装在 dispatch 调用中。所以它有效。

要使两个操作都有效,您应该将所有操作创建者包装在 dispatch 调用中。

可能的方法

const mapDispatchToProps = dispatch => ({
    generateReport: bindActionCreators(generateReport, dispatch),
    remoteSubmit: () => {
        dispatch(submit("privateForm"));
    }
});

另一种方法

const mapDispatchToProps = dispatch => ({
    generateReport: (value) => dispatch(generateReport(value)),
    remoteSubmit: () => {
        dispatch(submit("privateForm"));
    }
});

或者使用一个包含所有操作创建者的对象调用 mapDispatchToProps 。在这种情况下, connect 将为您调用 bindActionCreators

const mapDispatchToProps = {
    generateReport,
    remoteSubmit: () => submit("privateForm")
    }
Fyodor Yemelyanenko
2019-05-26