【问题标题】:Dispatch is not a function react调度不是一个函数反应
【发布时间】:2019-03-19 10:03:27
【问题描述】:

我正在开发一个使用 react 和 redux 的应用程序。我使用 api。

申请流程:

  • 填写表格,
  • 点击发送按钮,
  • 将数据从表单发送到 api,
  • 转到食谱页面

第一部分是您输入信息(姓名、卡路里、饮食类型)的表单。

    class FormPage extends Component {
      constructor(props) {
        super(props);

        this.handleFormSubmit = this.handleFormSubmit.bind(this);
        this.goToListOfMealPage = this.goToListOfMealPage.bind(this);
      }

      handleFormSubmit(data) {
        const name = data.name;
        const calories = data.caloreis;
        const diet = data.diet;
        const health = data.health;

        console.log(name)
        return loadData( name, calories, diet, health)()
          .then(({ error }) => {
            if (!error) {
              setTimeout(this.goToListOfMealPage, 1500);
            }

            return error;
          }
        );
      }

      goToListOfMealPage() {
        const { history } = this.props;
        history.push('/ListMeal');
      }

      render() {
        return (
          <Form onSubmit={this.handleFormSubmit}/>
        );
      }
    }

const mapDispatchToProps = (dispatch) => {
  return {
    loadData: () => dispatch(loadData())
  }
};

FormPage = connect(mapDispatchToProps)(FormPage)
export default FormPage;

handleFromSubmit函数是发送表单数据到api链接(https://api.edamam.com/search?q=${name}n&app_id=${key.id}&app_key=${key.key}&calories=${calories}&health=${健康}&diet=${diet})。

填完表格并点击发送按钮后,我想在新的子页面上有一份膳食(食谱)列表。

loadData 在哪里

const fetchDataStart = () => ({
  type: actionTypes.FETCH_DATA_START,
});

const fetchDataSucces = (data) => ({
  type: actionTypes.FETCH_DATA_SUCCESS,
  data,
});

const fetchDataFail = () => ({
  type: actionTypes.FETCH_DATA_FAIL,
});

const loadData = (name, calories, diet, health) => (dispatch) => {
  dispatch(fetchDataStart());
  return axios.get(`https://api.edamam.com/search?q=${name}n&app_id=${key.id}&app_key=${key.key}&calories=${calories}&health=${health}&diet=${diet}`)
    .then(({ data }) => console.log(data) || dispatch(fetchDataSucces(data)))
    .catch((err) => dispatch(fetchDataFail(err.response.data)));
};

发送表单后,我收到错误TypeError: dispatch is not a function

我找不到这个错误的原因

【问题讨论】:

  • 你能提供mapDispatchToProps吗? loadData(name, calories, diet, health)() - 当前调度是undefined
  • @BrianLe 我编辑了我的帖子。 const mapDispatchToProps = (dispatch) => { return { loadData: () => dispatch(loadData()) } };

标签: reactjs redux react-redux


【解决方案1】:

您的代码存在一些问题:

  • 如果你已经将 dispatch 映射到 prop,你可以通过 this.props.loadData(params) 调用动作
  • 您不应该通过这样做loadData()() 来调用该操作,因为调度的操作不会返回一个函数(尽管原始操作返回一个函数,但不要让它欺骗您)。

所以,要使用 loadData() 动作,您需要将其映射到道具,如下所示:

const mapDispatchToProps = dispatch => ({
  loadData: (name, calories, diet, health) => dispatch(loadData(name, calories, diet, health)),
});

然后像这样使用它:

componentDidMount() {
  this.props.loadData(name, calories, diet, health)
    .then(() => console.log('Success'))
    .catch(err => throw new Error("Error", err.stack))
}

编辑:根据您新编辑的问题,redux 中的 connect 函数分别接受 mapStateToPropsmapDispatchToProps,因此在您的代码中应该是:

export default connect(null, mapDispatchToProps)(Component)

【讨论】:

  • 感谢您的编辑。这为我节省了很多时间的调试时间。
【解决方案2】:
  1. 不需要您的构造函数 - 您可以通过这种方式自动绑定函数。

  2. 如果组件中没有mapStateToProps,则保持为null。

编辑代码:

import React from 'react';
// Your imports

class FormPage extends Component {
  handleFormSubmit = (data) => {
    const { name, caloreis, diet, health } = data;
    this.props.loadData(name, caloreis, diet, health);
  }

  goToListOfMealPage = () => {
    const { history } = this.props;
    history.push('/ListMeal');
  }

  render() {
    return (
      <Form onSubmit={this.handleFormSubmit} />
    );
  }
}

const mapDispatchToProps = dispatch => ({
  loadData: (name, caloreis, diet, health) => dispatch(loadData(name, caloreis, diet, health))
});

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

重定向建议:

  1. 您必须在 redux 状态下保持提交的成功和错误,如果成功 - 您可以重定向到 goToListOfMealPage - 您可以在 componentWillReceiveProps 中执行此操作。 我们应该执行类似于以下代码的操作:
class FormPage extends Component {
  componentWillReceiveProps(nextProps) {
    if (this.props.formSubmitSuccess !== nextProps.formSubmitSuccess && nextProps.formSubmitSuccess) {
      this.goToListOfMealPage()
    }
  }
  //... rest of the code.
}

// Your map state to props:
const mapStateToProps = state => ({
  formSubmitSuccess: state.reducerIdentifier.formSubmitSuccess,
  formSubmitFailure: state.reducerIdentifier.formSubmitFailure
});

【讨论】:

    猜你喜欢
    • 2020-09-16
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-29
    相关资源
    最近更新 更多