2017-09-25 61 views
1

假设一个具有下列组件文件HelloForm.jsx如何将数据异步加载到Redux中?

import React from 'react'; 
import {graphql} from 'react-apollo'; 
import {connect} from 'react-redux'; 
import {actions, Control, Form} from 'react-redux-form'; 
import {compose, withProps} from 'recompose'; 

import query from './HelloForm.gql'; 

const passThrough = fn => BaseComponent => props => { 
    fn(props, BaseComponent); 

    return BaseComponent(props); 
}; 

export const HelloForm = ({onSubmitEventHandler}) => 
    <Form 
      className="my-form" 
      model="forms.hello" 
      onSubmit={onSubmitEventHandler} 
    > 
     <label htmlFor="name">Name</label> 
     <Control.text 
      {...props} 
      model=".name" 
      id="name" 
     /> 

     <button type="submit">Say Hello</button> 
    </Form>; 

export const enhance = compose(
    connect(), 
    withProps({ 
     onSubmitEventHandler: ({name}) => { 
      window.alert(`Hello, ${name}`); 
     }, 
    }), 
    graphql(query), 
    passThrough(({data, dispatch, loading}) => { 
     if (!loading) { 
      dispatch(actions.load('forms.hello', data)); 
     } 
    }), 
); 

export default enhance(HelloForm); 

这似乎像预期的那样工作,但一个得到以下警告:

警告:setState(...):现有的状态转换过程中无法更新(如render或其他组件的构造函数)。渲染方法应该是道具和状态的纯粹功能;构造函数的副作用是反模式,但可以移动到componentWillMount

然而,React's component documentation表明应该分派componentDidMount生命周期事件期间的动作(其可以与功能组件经由recompose.lifecycle来完成)。但是没有道具提供给componentDidMount事件处理程序。

什么是“异步”分派行动到Redux的正确方法?

+1

检查是否有更新。我认为它可以帮助你。 – lilezek

+0

@lilezek,如果我理解正确,[Redux-Saga](https://github.com/redux-saga/redux-saga),仍然需要以类似的方式向Redux发送一个动作。 –

+0

是的,当然。如果您使用Redux,则不会避免分派操作。佐贺帮助你让Redux“不那么纯洁”。 – lilezek

回答

0

该解决方案确实使用recompose.lifecycle高阶组件。但是,不能使用箭头功能。更新的enchance高阶组件应执行如下:

export const enhance = compose(
    connect(), 
    withProps({ 
     onSubmitEventHandler: ({name}) => { 
      window.alert(`Hello, ${name}`); 
     }, 
    }), 
    graphql(query), 
    lifecycle({ 
     componentDidMount: function() { 
      const {dispatch, loading, recipe} = this.props; 

      if (loading) { 
       dispatch(actions.load('forms.hello', data)); 
      } 
     }, 
    }), 
);