组件在存储中删除后未卸载

Component is not unmount after its delete in store

项目 (Todolist) 是使用 immutable 库创建的,source here

存储结构:project 有很多 tasks,在 redux 存储中:State - 地图,projects, tasks - 记录

当我异步删除项目时...

export const removeProject = project => (dispatch) => {
  if (!isProjectExist(project)) return Promise.resolve()
  return projectService
    .delete(project)
    .then(
      () => {
        dispatch(remove(project))
        console.log("post removeProject resolved")
      },
      handleError,
    )
}

.. 初始化后创建的 - 它将被删除并正确卸载,但是当项目作为 initialState 传递时 - ProjectList 不会被重新渲染,并且 ProjectItem 尝试用陈旧的数据渲染自己,但失败了,如图


It have tests


看起来 reducer 返回更改的数据,但我使用 immutablejs,之前我使用 normalizr-immutable,但我认为这个库中的问题来源并编写了我自己的 normalizeInitialState (source), 它没有帮助,现在我认为问题的根源可能在 redux-immutable


我为解决这个问题苦苦挣扎了一整天


creator of redux says

I don't think this is something we can fix. React state changes are asynchronous and React may (or may not) batch them. Therefore, the moment you press “Remove”, the Redux store updates, and both Item and App receive the new state. Even if the App state change results in unmounting of Items, that will happen later than mapStateToProps is called for Item.

Unless I'm mistaken, there is nothing we can do. You have two options:

Request all required state at App (or a lower, e.g. ItemList) level and pass it down to “dumb” Items. Add safeguards to mapStateToProps for “currently unmounting” state. For example, you may return null from render in this case. Potentially we could have the component generated by connect() return null from its render if mapStateToProps returned null. Does this make any sense? Is this too surprising?

嗯,我从来没有在其他代码的 mapStateToProps 中看到像 return (<div></div>) 这样的存根或保护措施

马克里克森

I'm not entirely sure I follow what exactly your problem is, but as a guess: it sounds like the child component is re-rendering before the parent is. This is a known issue with React-Redux v4 and earlier. The v5 beta fixes that issue. Try installing react-redux@next and see if that takes care of your problem.