reduxjs / redux

A JS library for predictable global state management
https://redux.js.org
MIT License
60.85k stars 15.27k forks source link

Everything seems to need a UUID #1602

Closed dclowd9901 closed 8 years ago

dclowd9901 commented 8 years ago

This might be react-specific, but in order to reuse various reducers across components, it seems like every action creator and reducer needs to accept a UUID.

Let's suppose I have two items on my page, completely different aside from the fact that they can be visible or not visible. So we make a reducer that allows one to toggle visibility.

function visibility(state, action){
  switch(action.type) {
    case 'TOGGLE_VISIBLE': 
      state = !state;
    default:
      return state;
  }
}

And an action creator...

function toggleVisibility() {
  return {
    type: 'TOGGLE_VISIBLE'
  }
}

We combine the reducers...

// Component A
combineReducers({
  visibility
});

// Component B
combineReducers({
  visibility
});

We dispatch the action for item 1:

store.dispatch(toggleVisibility());

And now, both Components A and B's states have changed. The only way around this is to pass UUIDs to the action creators that then pass those to the reducers to consume and apply to their transformations on the store. This obviously leads to a lot of crufty code wherein you're passing UUIDs into absolutely everything.

I get the impression I'm "missing something", or maybe ignoring a pattern that would help here.

adamdonahue commented 8 years ago

Your combineReducers example is vague. What are you doing with the results of these calls?

adamdonahue commented 8 years ago

If I'm understanding your question correctly, though, you're right. There is only a single global state; therefore if you have two components using that state that are updating independent of one another you'll need to structure your state and actions to accommodate for that.

mxstbr commented 8 years ago

What @adamdonahue said is correct, you're dealing with a single global state so updating your state from somewhere will update it for both components!

adamdonahue commented 8 years ago

I do have one further comment. I tend to use Redux state to model business rules and state, and try to make UI state a function of that. So rather than a visibility state, I would probably store whatever business data is required to determine whether the widget is visible, and then, in connect, map that business logic to the local component state. This might also lead to a more natural solution to your problem.

If you're really just talking about toggling whether a component is visible on the screen for whatever reason, it might be a candidate for local UI state (using the traditional this.state variable on the component).

dclowd9901 commented 8 years ago

Thanks for your insights, guys. @adamdonahue it helps a lot more to know there's still a place for local ui state in a redux world.

markerikson commented 8 years ago

@dclowd9901 : yeah, "multiple instanced" data is still one of the big topics of discussion in the Redux world. The Redux FAQ partially covers this, at http://redux.js.org/docs/FAQ.html#organizing-state-only-redux-state. There's also at least a dozen community libraries that attempt to tackle this in various ways - I have most of them listed over at https://github.com/markerikson/redux-ecosystem-links/blob/master/component-state.md .

Finally, there's been a number of discussions here in this repo regarding this sort of topic. A quick search turns up the following relevant discussions: #1528 , #1182 , #822 , #569 , #1098 , #897 , and #1171 . Some relevant keywords are "Elm architecture" and "fractal". You might also want to look at https://github.com/slorber/scalable-frontend-with-elm-or-redux.

(This probably needs to be added to the FAQ.)

dclowd9901 commented 8 years ago

Awesome resources, thanks @markerikson.

eloytoro commented 7 years ago

I've recently made a project that tries to cover this situation for those who use react, let me know if it works for you. https://github.com/eloytoro/react-redux-uuid