0

我正处于 React+Redux 游戏的早期开发阶段,并遵循了 Redux 最佳实践:纯 reducer、展示/容器组件分离、getState()仅在 Reducer 中使用(而不是在动作创建者中)等。该应用程序似乎正在工作预期但是当我尝试使用 Time Travel 反转操作时,即使 state 属性map[][]及其计算的连接组件属性按预期更改,结果也不会正确反映在 UI 上(特别是地图上的玩家位置不会遵循国家规定)。当我检查状态变化时,我可以看到所有必要的变化都在不同状态之间正确发生。这是我的减速器:

const gridReducer = (state, action) => {

  if (typeof state === 'undefined'){
    let dungeon = new Dungeon();
    dungeon.generate();
    return {
      boardWidth: Math.floor(((70/100) * window.innerWidth) / 20),
      boardHeight: Math.floor(((70/100) * window.innerHeight) / 20),
      map: dungeon.map,
      position: dungeon.playerPosition
    }
  }
  switch (action.type) {
    case 'GRID_RESIZE': 
      return {...state, 
              boardWidth: action.newBoardWidth,
              boardHeight: action.newBoardHeight
      }
    //This is where I have the issue, map correctly changes both when interacting with the game and when reversing using time travel however the UI fails to update (only in reverse)!
    case 'MOVE':
      let dungeonObj = new Dungeon(state.map.slice(), {...state.position});
      if (dungeonObj.movePlayer(action.direction)) {
        return {...state,
                position: dungeonObj.playerPosition,
                map: dungeonObj.map
               }
      } else return state;
    default:
      return state;
  }
}

如果您想看一下,这是完整的代码!该应用程序目前仅支持通过按箭头键在地牢中移动玩家,并且视图应该始终基于玩家的位置居中(使用时间旅行时玩家无法向后移动) http://s.codepen。 io/sabahang/调试/GjrPNQ

PS:Dungeon.generate 确实使用了 Math.Random 但我只在initialState调度操作中使用这个函数我只是通过将当前状态发送到 Dungeon 构造函数并使用它的其他方法来制作生成地图的浅表副本(例如.movePlayer)

4

1 回答 1

1

找到了罪魁祸首。这根本不是 Redux 的错,而是 React 的工作方式!如果你是 React 新手,还没有落入这个陷阱,那就等着吧!这与以下事实有关,即在 Redux 中实现纯 Reducer 所需的大多数复制深度嵌套对象的传统方法实际上是对对象进行浅拷贝,并且属性的内存引用仍然指向原始对象状态。React 基于对旧状态和新状态的深入比较来更新 UI,当某些引用相同时,它无法正确更新 UI。这里我有一个二维数组map[][],它是一个对象,虽然我使用 ES6 扩展运算符来避免修改原始状态,因为正在制作影子副本,但原始索引的深度嵌套map[][]正在修改。一种解决方案是使用 `Array.map()' 创建一个全新的对象,但我最终使用了 immutablejs,它解决了我的时间旅行滑块问题。

如果您不想花数周时间在复杂的应用程序中寻找类似的错误,这是一个强烈推荐的参考:http ://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html

并且有大量的不变性助手可以根据您的特定需求提供帮助: https ://github.com/markerikson/redux-ecosystem-links/blob/master/immutable-data.md#immutable-update-utilities

这个也只对 Redux 很有趣: https ://github.com/indexiatech/redux-immutablejs

这个问题可能与以下问题重复: React-redux store updates but React does not

于 2016-10-05T04:30:58.263 回答