仅调度的最后一个操作到达reducer

时间:2018-03-11 07:25:13

标签: reactjs redux redux-thunk

我有一个用户输入名称的组件,在更改时需要执行两个操作:

  1. 更新组件的名称字段值
  2. 如果该名称已存在于
  3. 的entityType数据库中,则从服务器进行异步提取

    我使用thunk中间件进行异步工作,然后在thunk action creator中调度这两个动作。

    但是当在thunk动作创建器中传递动作时,只有最后调度的动作到达reducer(因此能够更新状态)。为什么会这样?我在哪里弄错了?

    感谢您的回答!

    相关的代码段是:

    namesection.js

    
    
    function NameSection({
        entityType,
        nameValue,
        onNameChange,
        warnIfExists
    }) {
        return (
            <div>
                <form>
                    <Row>
                        <Col md={6} mdOffset={3}>
                            <NameField
                                defaultValue={nameValue}
                                warn={warnIfExists}
                                onChange={onNameChange}
                            />
                        </Col>
                    </Row>
                </form>
            </div>
        );
    }
    
    function mapStateToProps(rootState) {
        const state = rootState.get('nameSection');
        return {
            nameValue: state.get('name'),
            warnIfExists: state.get('warnIfExists')
        };
    }
    
    function mapDispatchToProps(dispatch, {entityType}) {
        return {
            onNameChange: (event) =>
                dispatch(handleNameChange(event.target.value, entityType)),
        };
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(NameSection);
    &#13;
    &#13;
    &#13;

    action.js

    &#13;
    &#13;
    export function handleNameChange(
        newName,
        entityType
    ) {
        return (dispatch) => {
    
            dispatch({
                    meta: {debounce: 'keystroke'},
                    payload: newName,
                    type: UPDATE_NAME_FIELD
                });
    
            return request.get('/search/exists')
                .query({
                    collection: entityType,
                    q: newName
                })
                .then(res => dispatch({
                     meta: {debounce: 'keystroke'},
                     payload: res.text === 'true',
                     type: UPDATE_WARN_IF_EXISTS
                }))
                .catch((error: {message: string}) => error);
        };
    }
    &#13;
    &#13;
    &#13;

    reducer.js

    &#13;
    &#13;
    function reducer(
        state = Immutable.Map({
            name: '',
            warnIfExists: false
        }),
        action
    ) {
        const {payload, type} = action;
        console.log('reducer', payload, type);
        switch (type) {
            case UPDATE_NAME_FIELD:
                return state.set('name', payload);
            case UPDATE_WARN_IF_EXISTS:
                return state.set('warnIfExists', payload);
            // no default
        }
        return state;
    }
    &#13;
    &#13;
    &#13;

    在这种情况下,只更新warnIfExists,而名称字段不更新。

1 个答案:

答案 0 :(得分:0)

宣布整个按键事件处理程序似乎并不是一个好主意。这不会阻止角色立刻出现吗?

你有没有尝试过两次分裂?

    应始终分派
  1. UPDATE_NAME_FIELD并立即更改状态。
  2. CHECK_UNIQUE_NAME从同一个事件处理程序调度,但是被去抖动,然后在发出api请求之前从getState中检索当前值。然后这将导致CHECK_UNIQUE_NAME_SUCCESS,其中reducer处理结果,但同时检查名称是否已更改(以便旧值的api响应不会破坏状态)。