【问题标题】:Redux Toolkit: 'Cannot perform 'set' on a proxy that has been revoked'Redux Toolkit:'无法在已撤销的代理上执行'set''
【发布时间】:2021-02-01 17:46:28
【问题描述】:

我正在尝试使用 React 重新创建类似 Memory 的游戏。我正在使用 Redux Toolkit 进行状态管理,但我遇到了一个用例问题。

在 selectCard 操作中,我想将选定的卡片添加到商店,并检查是否已经选择了其中的 2 张。如果是这样,我想在延迟后清空selected 数组。

const initialState : MemoryState = {
    cards: [],
    selected: [],
}

const memorySlice = createSlice({
    name: 'memory',
    initialState: initialState,
    reducers: {        
        selectCard(state: MemoryState, action: PayloadAction<number>) {
            state.selected.push(action.payload);
            if (state.selected.length === 2) {
                setTimeout(() => {
                    state.selected = [];
                }, 1000);
            }
        }
    }
});

卡片选择得很好,但是当我选择 2 时,我会在 1 秒后收到此错误:

TypeError: Cannot perform 'set' on a proxy that has been revoked,上线state.selected = [];

我是这个东西的新手,我如何在延迟后访问状态?我必须异步执行吗?如果有,怎么做?

【问题讨论】:

    标签: reactjs redux redux-toolkit


    【解决方案1】:

    their documentation 中所述,不要在reducer 中执行副作用。

    我会在调度操作时添加 setTimeout:

    // so the reducer:
    ...
    if (state.selected.length === 2) {
      state.selected = [];
    }
    ...
    
    // and when dispatching
    setTimeout(() => {
      dispatch(selectCard(1))
    }, 1000)
    

    【讨论】:

    • 这只会将卡片的选择和清空数组延迟 1 秒:我正在寻找的是立即选择,如果条件为真,则在 1 秒后清空数组跨度>
    • 然后调度两个动作。 redux 的核心规则是 reducer 不能有任何副作用。
    【解决方案2】:

    我也遇到过这个问题。我通过在函数中使用“副作用”代码来解决它,然后在减速器中使用它的结果

    const initialState : MemoryState = {
      cards: [],
      selected: [],
    }
    
    const memorySlice = createSlice({
      name: 'memory',
      initialState: initialState,
      reducers: {        
        selectCard(state: MemoryState, action: PayloadAction<number>) {
            state.selected = action.payload
        }
      }
    });
    
    export const { selectCard } = memorySlice.actions
    
    export const sideEffectFunc = (param) => (dispatch) => {
      let selected = []
      selected.push(action.payload);
      if (selected.length === 2) {
         setTimeout(() => {
            selected = [];
         }, 1000);
      }
      dispatch(selectCard(selected));
    };
    

    不要关注函数的逻辑(没有测试过,可能是错的),但我想展示我们在使用 redux 工具包时处理“副作用”代码的方式

    【讨论】:

      猜你喜欢
      • 2020-09-27
      • 2023-03-25
      • 2021-10-25
      • 1970-01-01
      • 1970-01-01
      • 2021-02-14
      • 2020-12-17
      • 2021-10-23
      • 2019-11-08
      相关资源
      最近更新 更多