Redux Action не было отправлено - PullRequest
4 голосов
/ 25 мая 2019

Я работаю над реактивно-редукционным приложением. Теперь я столкнулся с проблемой отправки акции. Следующий код не может отправить действие 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) {

  }
};

Если я поменяю функцию подключения на

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

Это работает. Может кто-нибудь сказать мне, почему это не работает в первой ситуации? Благодаря.

1 Ответ

1 голос
/ 26 мая 2019

Это происходит из-за различного поведения 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")
    }
...