React-beautiful-dnd: Is there a way to prevent local state from resetting when moving components between lists?

Created on 8 Oct 2018  路  4Comments  路  Source: atlassian/react-beautiful-dnd

Example: https://codesandbox.io/s/488klj2y6x

If you change the state of the components, and then move them to another list then their local state is destroyed. Is there any way around this other than pulling their state into some parent component/context?

Before:
before

After:
after

Most helpful comment

component state will always reset because they get rerendered. either use a store like redux, or have your data in parent component, then pass to the child components in props. that way, whenever your data changes, you update the data in parent state, and childs will automatically get it from there, regardless of rerender

All 4 comments

component state will always reset because they get rerendered. either use a store like redux, or have your data in parent component, then pass to the child components in props. that way, whenever your data changes, you update the data in parent state, and childs will automatically get it from there, regardless of rerender

https://blog.arkency.com/2014/10/you-can-move-react-root-component-around/ describes a general technique to allow mounted React components to be freely moved around in the DOM while retaining state. The article is a bit dated (older APIs, and it doesn't use ReactDOM.createPortal which it should in order to let Context be passed down) but the general strategy is still just as valid. I've had success with this strategy.

There are open discussions to make this be directly supported by React: https://github.com/facebook/react/issues/3965, https://gist.github.com/chenglou/34b155691a6f58091953. (One of the comments of the first link mentions the strategy I referenced in the above paragraph: https://github.com/facebook/react/issues/3965#issuecomment-106205133)

When an item moves from one list to another it will be unmounted and remounted. So any local component state will be lost. You will need to store the state somewhere higher in the tree

Some options:

  • publish the state you care about to something on the context, and then when your component mounts try to pull the information back
  • dirty: store some state in the module itself and then try to re-hydrate your component when it mounts

A somewhat prettier possibility would be to move the actual items above the lists in the component hierarcy, and have each of them render through a React Portal into their respective lists. That way the items never get remounted, only their Portal target changes on drop.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

h182032 picture h182032  路  3Comments

ibash picture ibash  路  3Comments

Tsabary picture Tsabary  路  3Comments

alexreardon picture alexreardon  路  3Comments

jasonlewicki picture jasonlewicki  路  3Comments