在react redux应用程序上使用async / await的最佳约定

时间:2017-06-21 16:35:40

标签: reactjs redux async-await

我想知道我们在React Redux中使用async / await的不同方式(使用thunk) 如果有好的约定,它们是什么?我认为它很高兴:

  • 在容器中,不必使用promise then(),如this.props.myAction.then(...)
  • 我们不能在类方法中使用async关键字,而是在方法体中吗?例如:

    async doSomething(){   const data = await this.props.myAction()   的console.log(数据) }

    //但也许(如果行动与我的工作行动示例类似,那么它对我来说是失败的*见下文) 做一点事 () {   const handler = async()=> await this.props.myAction()//我想这里的await是多余的,但是为了清楚而增加了   const data = handler()   的console.log(数据) }

目前我的工作解决方案如下:

// MOCK data
const MOCK_DATA = [1, 2, 3, 4, 5]

// Action
export function myAction (payload) {
  return async (dispatch) => {
    const getter = () => {
      const promise = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve({serverResponse: MOCK_DATA})
        }, 1200)
      })
      return promise
    }

    try {
      return await getter()
    } catch (error) {
      console.log(error)
    }
  }
}

// Container
class Foobar extends Component {
  async doSomething () {
    const data = await this.props.myAction()
  }
  render () {
    return (
      <div>
        <button onClick={this.doSomething}>Do something!</button>
      </div>
    )
  }
}

1 个答案:

答案 0 :(得分:2)

“等待”的问题是你正在阻止事件循环,而你必须处理承诺&amp;调度员直接。

Thunk的替代方案更易于使用。 redux-auto

来自documantasion的

  

redux-auto简单地通过允许您创建一个返回promise的“action”函数来修复此异步问题。伴随你的“默认”功能动作逻辑。

  1. 不需要其他Redux异步中间件。例如thunk,promise-middleware,saga
  2. 轻松允许您将承诺传递给redux 并让它为您管理
  3. 允许您将外部服务呼叫与其转换位置共同定位
  4. 命名文件“init.js”将在应用启动时调用一次。这适用于从服务器开始加载数据
  5. 这个想法是让每个action in a specific file。将文件中的服务器调用与“pending”,“fulfilled”和“rejected”的reducer函数共同定位。这使得处理承诺非常容易。

    您的示例如下所示:

    // MOCK data
    const MOCK_DATA = [1, 2, 3, 4, 5]
    
    // data/serverThing.js
    export default function (data, payload, stage, result) {
    
      switch(stage){
        case 'FULFILLED':
            return result.serverResponse;
        case 'REJECTED':
            const error = result;
            console.log(error)
        case 'PENDING':
        default :
          break;
      }
      return data;
    }
    
    export function action (payload) {
      return Promise.resolve({serverResponse: MOCK_DATA})
    }
    
    // Container
    
    import React  from "react"
    import actions from 'redux-auto'
    import { connect } from 'react-redux'
    
    class Foobar extends Component {
    
      const loading = (true === this.props.data.async.serverThing) ? "loading..." : "";
    
      render () {
        return (
          <div>
            <button onClick={()=>actions.data.serverThing()}>Do something!</button> { loading }
          </div>
        )
      }
    }
    
    const mapStateToProps = ( { data }) => {
      return { data }
    };
    
    export default connect( mapStateToProps )(Foobar);
    

    它还会自动将helper object(called "async")附加到您所在州的原型,允许您在用户界面中跟踪请求的转换。