Search code examples
reduxnormalizationstate-managementnormalizr

How should I deep-duplicate state data in Redux?


I have several instances of state where I need to support actions that duplicate some slice of state. For example, my product is a survey builder, so when I duplicate a question, I'd also like to duplicate its answers, rather than have multiple questions pointing to the same answer instances.

The state is normalized:

questionsById: {
  q01: {
    ...
    answers: ["a01"],
    ...
  }
}
answersById: {
  a01: {...}
}

When dispatching an action of QUESTION_DUPLICATE, I'd like to also duplicate any answers. Currently my QUESTION_DUPLICATE action creator also creates a mapped list of new answer keys, and then the answer reducer consumes this.

This pattern seems unwieldy to me, especially when considering the possibility of deeper duplications (for example, duplicating a Page, which contains Questions, which contain Answers...). Is there a better pattern for deeply duplicating normalized data?


Solution

  • The answer may revolve around how you normally handle normalizing and denormalizing your data. For example, in my blog post Practical Redux, Part 8: Form Draft Data Management, I reuse my existing normalization logic (which leverages the redux-orm library) to copy an item to be edited between the "current" and "draft" slices in my state. So, similarly, one approach would be to denormalize the question you want to duplicate, and then re-normalize it (in either the action creator or the reducer, as you see fit).