如何异步将数据加载到Redux?

时间:2017-09-25 19:47:11

标签: javascript reactjs redux react-redux react-redux-form

假设有一个组件文件HelloForm.jsx

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 个答案:

答案 0 :(得分: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));
            }
        },
    }),
);