New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redux is great but major feature is missing... #1300

Closed
born2net opened this Issue Jan 28, 2016 · 9 comments

Comments

6 participants
@born2net

born2net commented Jan 28, 2016

Redux is a great modeling pattern that I am sure will continue and grow...
I have been using a single source of truth type models for many years and I am happy yo see its becoming popular in the JS eco system.

However Redux is missing a critical part as currently it focuses more on the producer and less on the consumer.
Let me explain, I am talking about the:

let unsubscribe = store.subscribe(() =>
  console.log(store.getState())
)

currently when an action is produced, all subscribers will receive the callback, however if you ever developed a large application, or worst yet, had to jump into someone else's code you know that the biggest issue is finding your way around. And so if I look at a reducer which is switching on some list of action, I would like to be able to see all the places in the code base that "cares" about a particular (like we always do with events), just right click on the action in your favorite IDE and select find usage.

now I understand that with reducers you can divide the application to multiple smaller reducers to so its easier to find things... BUT, if you are going to refactor a line of code, you want to make sure all subscribers that rely on it will not explode...

The cleanest way to get that is simply to pass the action to the subscriber as in:

let unsubscribe = store.subscribe((typeAction:string) =>
  if (typeAction === Consts.FOO)
    console.log('found foo'); 
 console.log(store.getState())
)

and we can find all places in the code that refer to Consts.FOO when we refactor...

It will be much easier to reason about how changes propagate in a large application if we can get the action to be passed to the subscribers.

The second point (which may or may not be valid) is why isn't the store reference passed as well just to save a single line of code: store.getState();

so instead wouldn't that be better:

let unsubscribe = store.subscribe((store:Redux.store, typeAction:string) =>
  if (typeAction === Consts.FOO) {
      console.log('I got my store);
  }
)

If we already have a subscriber we might as well use it to pass relevant parameters.

Thanks for a great framework and hope we can get it even better,

regards

Sean - founder of http://DigitalSignage.com

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Jan 28, 2016

Collaborator

It will be much easier to reason about how changes propagate in a large application if we can get the action to be passed to the subscribers.

Can you please explain on a specific scenario how that would make code easier to understand? In Redux you should re-render UI based on current state, not the action. By the time the state is returned from the reducer, the action doesn't matter anymore. For debugging, you can use redux-logger:

Also this has been discussed in quite a few issues:

#251
#347
#580
#622
#1057
#1091
#1243

The second point (which may or may not be valid) is why isn't the store reference passed as well just to save a single line of code: store.getState();

Please see #303.

In general it’s best to search for issues first 😉

Collaborator

gaearon commented Jan 28, 2016

It will be much easier to reason about how changes propagate in a large application if we can get the action to be passed to the subscribers.

Can you please explain on a specific scenario how that would make code easier to understand? In Redux you should re-render UI based on current state, not the action. By the time the state is returned from the reducer, the action doesn't matter anymore. For debugging, you can use redux-logger:

Also this has been discussed in quite a few issues:

#251
#347
#580
#622
#1057
#1091
#1243

The second point (which may or may not be valid) is why isn't the store reference passed as well just to save a single line of code: store.getState();

Please see #303.

In general it’s best to search for issues first 😉

@gaearon gaearon closed this Jan 28, 2016

@gaearon gaearon added the question label Jan 28, 2016

@born2net

This comment has been minimized.

Show comment
Hide comment
@born2net

born2net Jan 28, 2016

I think you may have missed the point, this is not for better coding, but safer refactoring as you can find the places that care about the result of an action,

regards

Sean

born2net commented Jan 28, 2016

I think you may have missed the point, this is not for better coding, but safer refactoring as you can find the places that care about the result of an action,

regards

Sean

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Jan 28, 2016

Collaborator

I think you may have missed the point, this is not for better coding, but safer refactoring as you can find the places that care about the result of an action,

I don't understand what kind of code you are refactoring. If subscribers can't know about the action in the first place, how does passing it help refactoring? Some specific real-world examples will help.

Collaborator

gaearon commented Jan 28, 2016

I think you may have missed the point, this is not for better coding, but safer refactoring as you can find the places that care about the result of an action,

I don't understand what kind of code you are refactoring. If subscribers can't know about the action in the first place, how does passing it help refactoring? Some specific real-world examples will help.

@markerikson

This comment has been minimized.

Show comment
Hide comment
@markerikson

markerikson Jan 28, 2016

Contributor

@born2net : isn't that the point of using named constants in your actions and reducers?

Contributor

markerikson commented Jan 28, 2016

@born2net : isn't that the point of using named constants in your actions and reducers?

@born2net

This comment has been minimized.

Show comment
Hide comment
@born2net

born2net Jan 28, 2016

not really, since any store changes are propagated everywhere... regardless...

born2net commented Jan 28, 2016

not really, since any store changes are propagated everywhere... regardless...

@ffxsam

This comment has been minimized.

Show comment
Hide comment
@ffxsam

ffxsam Mar 11, 2016

I stumbled upon this and also found a situation where I want a component to react to action, not state.

http://stackoverflow.com/questions/35930677/is-there-a-way-to-have-a-react-container-respond-to-a-redux-action

The list of members in an organization is nothing I want to store in the global state, doesn't make any sense. However, I want my component to know when the thunk dispatches a "success" action so it can do something (force a re-render).

ffxsam commented Mar 11, 2016

I stumbled upon this and also found a situation where I want a component to react to action, not state.

http://stackoverflow.com/questions/35930677/is-there-a-way-to-have-a-react-container-respond-to-a-redux-action

The list of members in an organization is nothing I want to store in the global state, doesn't make any sense. However, I want my component to know when the thunk dispatches a "success" action so it can do something (force a re-render).

@johnsoftek

This comment has been minimized.

Show comment
Hide comment
@johnsoftek

johnsoftek Mar 11, 2016

Contributor

Why does the component need to re-render if state has not changed?

On 11 March 2016 at 11:40, Sam notifications@github.com wrote:

I stumbled upon this and also found a situation where I want a component
to react to action, not state.

http://stackoverflow.com/questions/35930677/is-there-a-way-to-have-a-react-container-respond-to-a-redux-action

The list of members in an organization is nothing I want to store in the
global state, doesn't make any sense. However, I want my component to know
when the thunk dispatches a "success" action so it can do something (force
a re-render).


Reply to this email directly or view it on GitHub
#1300 (comment).

Contributor

johnsoftek commented Mar 11, 2016

Why does the component need to re-render if state has not changed?

On 11 March 2016 at 11:40, Sam notifications@github.com wrote:

I stumbled upon this and also found a situation where I want a component
to react to action, not state.

http://stackoverflow.com/questions/35930677/is-there-a-way-to-have-a-react-container-respond-to-a-redux-action

The list of members in an organization is nothing I want to store in the
global state, doesn't make any sense. However, I want my component to know
when the thunk dispatches a "success" action so it can do something (force
a re-render).


Reply to this email directly or view it on GitHub
#1300 (comment).

@mbensch

This comment has been minimized.

Show comment
Hide comment
@mbensch

mbensch Mar 11, 2016

@ffxsam From what I understand is that you want to have a component react directly on the response of an async action rather than storing that data in the state and having the component react to a state change?

That would break the idea of a unidirectional data flow because you'd be bypassing the reducers and have a component tightly coupled to an external entity (your API responses). This kind of defeats the purpose of using redux (or a single state atom). If it's a whole lot of data you can look into paging, memoizing etc. Or just clean up the state when you leave the module/page and don't need the data anymore and then refetch from server or cache on next visit.

Just a couple of ideas :)

mbensch commented Mar 11, 2016

@ffxsam From what I understand is that you want to have a component react directly on the response of an async action rather than storing that data in the state and having the component react to a state change?

That would break the idea of a unidirectional data flow because you'd be bypassing the reducers and have a component tightly coupled to an external entity (your API responses). This kind of defeats the purpose of using redux (or a single state atom). If it's a whole lot of data you can look into paging, memoizing etc. Or just clean up the state when you leave the module/page and don't need the data anymore and then refetch from server or cache on next visit.

Just a couple of ideas :)

@ffxsam

This comment has been minimized.

Show comment
Hide comment
@ffxsam

ffxsam Mar 11, 2016

I think actually this is a sign of poor architecture on my part. :) I went back through my code, and I'm passing a container's state object rather than actual live data. I think I need to do some serious refactoring.

ffxsam commented Mar 11, 2016

I think actually this is a sign of poor architecture on my part. :) I went back through my code, and I'm passing a container's state object rather than actual live data. I think I need to do some serious refactoring.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment