将数据POST到服务器并使用redux处理响应的正确方法

时间:2017-12-19 19:12:49

标签: reactjs redux react-redux

我很反应和减少。

现在我想用redux进程重写我的post请求。

我当前的请求如下:

  _handleSubmit(event) {
    axios
      .post('/createUrl', {
        url: this.state.url
      })
      .then((response) => {
        this.setState({
          shortenInfos: response.data
        })
      })
      .catch((error) => {
        console.log(error);
      });

    event.preventDefault()
  }

现在我创建了一个商店:

export default function url(state = 0, action) {
  switch (action.type) {
    case 'CREATE_URL':
      // maybe axios request?!
      return `${action.url}/test`
    case 'CREATED_URL':
      return `${action.url}/created`
    default:
      return state
  }
}

所以我必须使用store.dispatch()?我应该让我的_handle提交这样的东西吗?

_handleSubmit(event) {
  axios
    .post('/createUrl', {
      url: this.state.url
    })
    .then((response) => {
      store.dispatch({
        type: 'CREATED_URL',
        url: response.data
      })
    })
    .catch((error) => {
      console.log(error);
    });

  event.preventDefault()
}

我认为这是错的?我必须在哪里使用mapStateToProps方法?或者我应该在我的reducer中的CREATE_URL中执行axios-request?

1 个答案:

答案 0 :(得分:6)

简介

将React与Redux结合使用,可以让您高度自由地执行操作。这样做的缺点是很难找到应该如何正确完成的事情,主要是因为没有标准或全面的指南来使用正确实现的项目所需的许多依赖项。这个答案将指导您完成基础知识,并提供参考链接,帮助您了解下一步以及如何深入了解您的知识。

减速

Reducers should be pure ,意味着它们没有副作用(比如制作axios请求),它们应该始终返回一个新的对象/数组/值,而不是更改以前的状态。 use action types as constants 也是一种很好的做法。您可以在任何地方放置操作类型,但为了简单起见,我会将它们放入reducer的文件中,但有better ways to organize them like using ducks

export const CREATED_URL = 'CREATE_URL';

export default const url = (state = '', action) => {
  switch (action.type) {
    case CREATED_URL:
      return action.url;
    default:
      return state;
  }
};

异步操作

导致副作用的一切都应该是一个动作,所以XHR应该在那里发生。由于XHR应该是异步的,因此建议使用中间件:redux-thunkredux-saga是两种流行的解决方案。我会和thunk一起去install it first

首先(因为const has temporal dead zone)你需要一个能够加载" XHR对商店的结果:

import { CREATED_URL } from './reducer';

const createdUrl = url => ({
  type: CREATED_URL,
  url, // ES6 trailing comma for prettier git diffs
});

然后,您可以创建将触发XHR的操作,等待响应,然后使用先前创建的操作将其加载到商店。我们需要返回一个接收dispatch作为参数的函数。此技术用于函数式编程,称为currying

export const createUrl = url => dispatch => { // with only 1 parameter the parentheses can be omited
  axios
    .post('/createUrl', { url }) // ES6 Shorthand property name in { url }
    .then(response => {
      dispatch(createdUrl({
        url: response.data,
      })
    })
    .catch(error => {
      // @TODO dispatch an action that will show a message
      // notifying the user that the request failed
      console.log(error);
    }); 
}

React组件中的用法。

制备

为了便于使用,您需要将React组件与Redux连接。 react-redux来救援。阅读API documentation并将<Provider>组件添加到React组件树的根目录。

现在,在React组件文件的顶部,导入所有必要的内容:

import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { createUrl } from './reducer';

mapStateToPropsmapDispatchToProps

然后为connect创建两个辅助函数:

const mapStateToProps = store => ({ url: store.url })

const mapDispatchToProps = dispatch => bindActionCreators({ createUrl }, dispatch)

mapStateToProps的帮助下,您可以订阅商店更新,并将Redux商店的重要部分注入您的组件propsmapStateToProps应该返回一个将合并到组件props的对象。通常我们只是做store => store.url之类的事情,但是因为我们的例子非常简单以至于reducer返回一个普通字符串而不是对象中更复杂的字符串,我们需要将该字符串包装到这里的对象中。

bindActionCreators的帮助下,

mapDispatchToProps会将传递的操作注入到组件的props中,以便我们可以轻松调用并将其传递给子组件:{{1 }}

组件本身

现在我们可以创建组件本身。我将使用ES6类来显示this.props.createUrl()的示例,但如果您不需要它并且您有无状态组件,那么您也可以使用函数。

componentDidMount