React redux React组件在链接redux saga中的操作时未接收到中间状态

React redux React组件在链接redux saga中的操作时未接收到中间状态,react-redux,redux-saga,React Redux,Redux Saga,我有两个操作TEST和TEST\u DONE,这两个操作都会在我的redux状态中增加一个id属性。每当我从我的组件分派第一个动作TEST时,我使用redux saga自动分派第二个动作TEST\u DONE 我希望执行顺序如下: 组件以初始值testState.id=0 组件分派测试操作 使用testState.id=1 saga发送TEST\u DONE操作 使用testState.id=2 相反,只有当testState.id更新为2时,我的组件才会重新呈现。我在getSnapshotBe

我有两个操作
TEST
TEST\u DONE
,这两个操作都会在我的redux状态中增加一个
id
属性。每当我从我的组件分派第一个动作
TEST
时,我使用redux saga自动分派第二个动作
TEST\u DONE

我希望执行顺序如下:

  • 组件以初始值
    testState.id
    =
    0
  • 组件分派
    测试
    操作
  • 使用
    testState.id
    =
    1
  • saga发送
    TEST\u DONE
    操作
  • 使用
    testState.id
    =
    2
  • 相反,只有当
    testState.id
    更新为
    2
    时,我的组件才会重新呈现。我在
    getSnapshotBeforeUpdate
    函数中看不到
    1
    值。它将
    0
    显示为上一个道具

    为什么道具从
    0
    跳到
    2
    ,但中间没有接收到
    1


    saga.js:

    export function* TestSagaFunc() {
        yield put({
            type: actions.TEST_DONE
        });
    };
    
    export default function* rootSaga() {
        yield all([
            yield takeEvery(actions.TEST, TestSagaFunc),
        ]);
    };
    
    action.js:

    const actions = {
        TEST: 'TEST',
        TEST_DONE: 'TEST_DONE',
    
        callTest: (id) => ({
            type: actions.TEST,
            payload: {
                id
            }
        }),
    };
    export default actions;
    
    reducer.js:

    const initState = {
        testState:  {
            id: 0
        }
    };
    
    export default function TestReducers ( state=initState, { type, ...action}) {
        switch(type) {
        default:
            return state;
        case actions.TEST: {
            const { id } = state.testState;
            const nextId = id + 1;
            return {
                ...state,
                testState: {
                    ...state.testState,
                    id: nextId
                }
            };
        };
        case actions.TEST_DONE: {
            const { id } = state.testState;
            const nextId = id + 1;
            return {
                ...state,
                testState: {
                    ...state.testState,
                    id: nextId
                }
            };
        }
    };
    };
    
    组件的控制台输出
    getSnapshotBeforeUpdate


    总结我对问题的评论:

    正如您所看到的,redux状态确实正在更新,但是组件不能保证根据状态更改的方式呈现每个中间状态更改。要测试这一点,您可以尝试从
    redux saga/effects
    导入
    delay
    ,并添加
    产量延迟(1000)之前,在
    TestSagaFunc
    中放入
    yield put
    ,这样两个状态更新就不会批处理在一起


    这只是一个演示批处理效果的技巧,几乎肯定不是您想要做的。如果需要渲染中间状态,可以从使用
    useffect
    (或
    componentdiddupdate
    )渲染的组件中分派
    TEST\u DONE
    ,以确保组件使用中间状态经历一个渲染周期。但无法强制组件渲染批处理在一起的中间减速器状态。

    正如您所看到的,状态确实正在更新,但并不保证在每次状态更改时都会进行组件渲染。尝试从
    redux saga/effects
    导入
    delay
    ,并
    产生延迟(1000)TestSagaFunc
    中的
    yield put
    之前,请执行code>,这样两个状态更新就不会被批处理在一起了。@azundo感谢您的回复,您是对的。我试着像你说的那样导入,但我认为这只是一个骗局。你还有什么别的事情要彻底处理吗?是的,这只是个骗局。如果需要渲染中间状态,可以使用
    useffect
    (或
    componentdiddupdate
    ,以确保组件使用更新的状态经过一个渲染周期。但无法强制组件渲染中间还原器状态,这些状态在渲染周期之间更新。这是我对redux传奇的缺乏了解。传奇帮助我们处理副作用,但我的st不是。你分享的信息非常有用,我解决了我的问题。非常感谢@azundo@azundo我不得不阅读这个问题和你的评论几次,以了解你的意思。我的第一个想法是“当redux状态改变时,组件肯定会重新呈现”.但我在这里看到,我们讨论的是一个立即被覆盖的中间更改。因此,这归结为如何更新,这是我理解得不够透彻,无法解释的。