-
Notifications
You must be signed in to change notification settings - Fork 18
chat about flux on discord
https://discordapp.com/channels/102860784329052160/102860784329052160
catmando - Today at 8:47 PM
hi is this right place to ask a basic question about the flux architecture?
acemarke - Today at 8:47 PM
@catmando : yup
catmando - Today at 8:47 PM
cool
so the flux "loop" sounds great, but actually I am not seeing the "loop"
store sends some data update to a component -> component gets clicked by user -> component uses action creator to create an action -> action gets dispatched -> store receives action and updates....
did I get that right?
acemarke - Today at 8:49 PM
pretty much, yeah
catmando - Today at 8:49 PM
so what I am not getting is this
it looks like a ton of intermediate steps between component gets clicked by user, just to basically call some method on a store class and update the data
it just looks like this really:
store sends data to component -> component sees user click -> component updates store
what is the point of all the intermediaries between the component back to the store?
acemarke - Today at 8:52 PM
hmm. so, first caveat: I never really got all that far into the "original Flux" concepts myself
I started learning React in the summer of 2015, right after Redux had come out
I'm intimately familiar with how the concepts work in regards to Redux, but somewhat less so in regards to "original Flux"
or any of the five million Flux-like libraries
catmando - Today at 8:54 PM
but the basic conceopt is the same right? It seems like there is a big deal about the "dispatcher" why not just call a method back on a class / store / whatever and tell it to update?
acemarke - Today at 8:54 PM
aha. so THAT is the big aspect
here's an article from when Facebook first announced the Flux concept: https://www.infoq.com/news/2014/05/facebook-mvc-flux
InfoQ
Facebook: MVC Does Not Scale, Use Flux Instead [Updated]
This article has been updated based on community and Jing Chen (Facebook)’s reaction. (See the Update section below.) Facebook came to the conclusion that MVC does not scale up for their needs and has decided to use a different pattern instead: Flux.
note this diagram:
catmando - Today at 8:55 PM
OHHH I agree with that 100% (nice diagram BTW and thanks)
acemarke - Today at 8:55 PM
I saw this kind of thing myself working on a Backbone app
any piece of the code can call someModel.set() at any time
and in the case of Backbone, change events can trigger other updates
next thing you know, you've got a call stack with 15 different event triggers in a row
now, those may all be synchronous, so you can walk back the call stack and see what happened
but the idea of "any code can modify any state at any time" is the root issue
this is also related to why React discourages the idea of "2-way data binding"
so, the basic idea of Flux is that you start moving all that "write" logic into a consistent location
and "dispatch" a descriptive "action" to trigger it
catmando - Today at 8:57 PM
sure we all know that picture 😃
acemarke - Today at 8:58 PM
the store updates, components pull in the new data, and re-render
so yes, it's adding a layer or two of indirection
but the idea is that the data flow is much more predictable
Redux then takes that a couple steps further
rather than having multiple stores, there's only one store
and there's only one function that does all the updating
that one "root reducer" function can actually be made up of many smaller functions internally
catmando - Today at 8:58 PM
one step at a time partner, I'm not past that flux picture yet 😃
acemarke - Today at 8:58 PM
:)
catmando - Today at 8:59 PM
that picture is where I am stuck because
catmando - Today at 9:00 PM
it just seems that in the end the view is "sending" a message right around back to the store. What is the value being added by the the action object, and the dispatcher?
is just because the dispatcher "queues" thing up or something?
acemarke - Today at 9:01 PM
so, the "dispatcher" is basically a singleton
Jesus - Today at 9:01 PM
Flux architecture is of the opinion that one way data flow is inherently superior to other models of structuring your application
acemarke - Today at 9:01 PM
ye olde Global Variable Of Doom
and no, I don't think any flux implementations do any queueing
I'd have to review the original concept of why there's an "action object"
I know why it exists in Redux, but not original Flux
catmando - Today at 9:02 PM
so... then effectively if I walk around that picture, I send a message (and action object) it goes to the dispatcher, the dispatcher sends it the store, if its all happening syncronously then what is the point?
Jesus - Today at 9:02 PM
the dispatcher calls out to one or potentially multiple stores
the point is one way data flow
catmando - Today at 9:03 PM
@Jesus yeah I do see that advantage is some cases.... I.e. you can decouple the action from the specific store(s)
Jesus - Today at 9:04 PM
This way my applications components only have one source of truth
the stores
which can only be updated unidirectionally
catmando - Today at 9:04 PM
@Jesus but what I am not seeing (perhaps Im being dumb) is where its actually controlling the flow.... if the component calls the dispatcher, and the dispatcher calls back to the store, then effectively you are directly calling the store...
acemarke - Today at 9:04 PM
if it helps, I've got a category for Flux tutorials in my React/Redux links list : https://github.com/markerikson/react-redux-links/blob/master/flux-tutorials.md
GitHub
markerikson/react-redux-links
react-redux-links - Curated tutorial and resource links I've collected on React, Redux, ES6, and more
@catmando : there could be multiple stores
all registered with the dispatcher
catmando - Today at 9:05 PM
RE: multiple stores, is 1) of (2) advantages that I do see
advantage (2) is that if everything goes through the dispatcher, its easy to log for debug purposes
bottom line (as far as I can see) is that an event calls the dispatcher, and the dispatcher calls back to the store.
vcarl - Today at 9:07 PM
if its all happening syncronously then what is the point?
part of the point is to deliberately add constraints. MVC's lack of constraints leads to the spiderweb of updates; constraining it to a single event at a time means there's less going on at a given time, and so your app is easier to reason about
catmando - Today at 9:07 PM
so what is so wrong with the event just calling the store directly?
acemarke - Today at 9:08 PM
that's what I was saying a minute ago
there could be multiple individual Flux Stores in one application
UserStore, SomeItemStore, SomeOtherItemStore, etc
each one gets registered with the dispatcher, and may or may not respond to a given dispatched action
so, a component that wants to dispatch an action doesn't know which ones there are, or who's going to respond
the Dispatcher is the single piece that handles that
so, there's some decoupling of "here's the thing that happened" from "here's what got updated in response"
catmando - Today at 9:10 PM
Right I got that, but out of the many actions in a real world app, how many actually are effectiing multiple stores?
acemarke - Today at 9:10 PM
(boy, this is the "Are Redux actions 1:1 with reducers?" question all over again :) )
vcarl - Today at 9:10 PM
i'd say the benefit is less that actions dispatch to multiple stores and more that you don't have to consider which store to dispatch to
acemarke - Today at 9:10 PM
so here's an example from my own Redux app
Jesus - Today at 9:10 PM
Its pretty easy to think of many examples
catmando - Today at 9:10 PM
FYI - as I said before no fan of MVC, definitely want alternatives
vcarl - Today at 9:10 PM
it's not a question. you just dispatch via the dispatcher
acemarke - Today at 9:10 PM
in my app, the user always has a "project" open
whenever they load a different project from the server, my application:
- Clears out the old data for the project
- loads in the data for the new project
- If an item was being edited, cancels the edit
- If an item was selected, deselects it
- Sets the name of the current project
- Clears out stuff that was displayed on the map
In Flux terms, those are all being handled by different "stores"
well, first two are an overlap, but yeah
Jesus - Today at 9:12 PM
I have an application with documents, users, and companies. The documents have data related to companies and users. I have 3 stores for maintaining the state of these separate entities
catmando - Today at 9:12 PM
@acemarke Yeah I get that example, and in any app there are several of those cases (mine too)
but most events (to me anyway) are the more common, todo gets marked complete
acemarke - Today at 9:12 PM
so, semantically one action (PROJECT_LOAD), and many different data updates as a result
sure, and as I've seen with Redux apps, that 1:1 correspondence is more common
but multiple response is entirely possible and useful :)
catmando - Today at 9:13 PM
@acemarke don't get me wrong that is a great reason to dispatch, plus the decoupling, but that has nothing to do with 1-way data flow
acemarke - Today at 9:13 PM
I feel like we're going in a 1-way circle here... :)
catmando - Today at 9:13 PM
😃
its a very helpful discussion, and I appreciate it very much!
acemarke - Today at 9:14 PM
the 1-way data flow aspect is that the component isn't directly modifying the data itself
ie, in a Backbone.View, you could call this.model.set("someField", someValue)
in a Flux app, that doesn't happen
vcarl - Today at 9:14 PM
and that data from the store(s) isn't used to update the store
catmando - Today at 9:14 PM
I guess that is my point It is directly modifying the data
acemarke - Today at 9:14 PM
nope
the act of dispatching an action decouples the write process from the dispatch
it may be synchronous
catmando - Today at 9:15 PM
not seeing it sorry
acemarke - Today at 9:15 PM
but the dispatch itself is different than the act of making the update
the data is encapsulated in the stores
the component never modifies that data in the stores
catmando - Today at 9:16 PM
component sends to dispatcher
dispatcher sends to store
acemarke - Today at 9:16 PM
but the component isn't doing the modifications itself
that's the key
catmando - Today at 9:16 PM
if I hire joe to kill sam
I am guilty of killing sam
if I hire the dispatcher to send a message to the store
then...
acemarke - Today at 9:17 PM
I'm not sure what else to say to explain the idea here
vcarl - Today at 9:17 PM
{type: 'KILL', payload: {target: 'sam'}} vs Sam.setAlive(false)(edited)
declarative vs imperative
catmando - Today at 9:18 PM
one looks kind of like LISP, the other looks kind of like JS, but both look semantically the same
just syntax is different
acemarke - Today at 9:18 PM
nope
catmando - Today at 9:18 PM
method = KILL / Sam.setAlive
acemarke - Today at 9:18 PM
^^^
Jesus - Today at 9:19 PM
lol
jsonnull - Today at 9:19 PM
Instead of encapsulating all behavior, logic, rendering, etc. together, we let ONE thing handle all modifications to state completely separately
Jesus - Today at 9:19 PM
Its just an opinionated way of structuring your application.
ntkoso - Today at 9:19 PM
you can't serialize imperative calls
catmando - Today at 9:20 PM
@vcarl said it all: {type: 'KILL', payload: {target: 'sam'}} vs Sam.setAlive(false)
acemarke - Today at 9:20 PM
serialization's a related aspect, but not the core piece of 1-way data flow itself
Jesus - Today at 9:20 PM
You could just use Angular 1
biblethump1
acemarke - Today at 9:20 PM
pukes
catmando - Today at 9:20 PM
double pukes
not arguing here, just trying desparetly to udnerstand
jsonnull - Today at 9:20 PM
It's less about "where is the decision to change data" coming from, and more about "who has the privilege of actually modifying data"
acemarke - Today at 9:20 PM
^^^
which is what i was trying to say a minute ago
vcarl - Today at 9:21 PM
this is rapidly gonna go off the rails with 4 people trying to explain simultaneously
jsonnull - Today at 9:21 PM
Sorry XD
ntkoso - Today at 9:21 PM
ahaha, this conversation 😃
jsonnull - Today at 9:21 PM
Just trying to get that one insight out there
acemarke - Today at 9:21 PM
the component itself does not contain a line like theData.someField = 123(edited)
vcarl - Today at 9:21 PM
haha no i totally understand i hopped in too
❤1
catmando - Today at 9:21 PM
its great and thanks guys
acemarke - Today at 9:22 PM
I gotta bail on this conversation at this point. Need to tackle writing the other half of my "Practical Redux Part 8" blog post
catmando - Today at 9:22 PM
I'm just stuck right here
jsonnull - Today at 9:22 PM
Good luck @acemarke 😃
catmando - Today at 9:22 PM
you need go no farther than explaining why semantically these are different
@vcarl said it all: {type: 'KILL', payload: {target: 'sam'}} vs Sam.setAlive(false)
acemarke - Today at 9:22 PM
@catmando : I'd encourage you to read through the Flux articles at https://github.com/markerikson/react-redux-links/blob/master/flux-tutorials.md , as well as other articles in that repo
GitHub
markerikson/react-redux-links
react-redux-links - Curated tutorial and resource links I've collected on React, Redux, ES6, and more
vcarl - Today at 9:22 PM
@catmando, lemme phrase it differently
acemarke - Today at 9:23 PM
vcarl - Today at 9:24 PM
@catmando:
think jQuery vs React.
if (condition) {
$('.some-class').addClass('stuff').innerHTML('some child')`
}
vs
render() {
return <div className={`some-class ${condition? 'stuff' : ''}}>
{condition? 'some child' : null}
}
same thing right?
no differences at all
catmando - Today at 9:25 PM
reading...
vcarl - Today at 9:25 PM
jquery is imperative, react is declarative
catmando - Today at 9:26 PM
that is cool
vcarl - Today at 9:26 PM
doing this imperatively works, but you prescribe the details, which means that if the details change, you have to rewrite all the logic
catmando - Today at 9:26 PM
and most of it I get
I just don't get really this one thing
how is {type: 'KILL', payload: {target: 'sam'}} any different than People.kill('sam') EXCEPT that the first does ALLOW multiple receivers...
vcarl - Today at 9:26 PM
that is literally what i'm explaining
one sec
since flux actions are declarative, they add some decoupling between your UI and your app's behavior. let's say instead of storing a boolean value for whether somebody's alive, now you need to track an integer for how much health they have
so now you need to find anywhere that did Sam.setAlive(false) and change it to Sam.setHealth(0)
but your flux action doesn't change, just the implementation
every component still dispatches the same action, and has no idea that now it's setting an integer to 0
catmando - Today at 9:30 PM
@vcarl with you 100% so far
vcarl - Today at 9:31 PM
i mean that's most of it, really
there's some more arguments about performance and "update storms" with large MVC apps, but those examples are hard to come up with
complex derived data in MVC leads to a lot of cognitive overheard, which makes it hard to make changes without unpredictably breaking something else
with you can do a project wide search for all stores (or reducers in redux) responding to action type KILL and change them, confident that you didn't miss anything
catmando - Today at 9:33 PM
@vcarl so let me flip you example around
jsonnull - Today at 9:33 PM
You can think about declarative as "describing intent"—with declarative actions, your components communicate intent and then you have one place where that intent is translated into actual mutations. This clean separation is really nice to have.
catmando - Today at 9:33 PM
say I had this action
timboslive - Today at 9:33 PM
hey guys and gals, can I get a recommendation on what lib to use for responsive styles/media queries? I am use react/redux.
vcarl - Today at 9:34 PM
@timboslive doesn't really come into react, more of a styling question
BTM - Today at 9:34 PM
You really dont need a lib for responsive styles. There are some for responsive components though
catmando - Today at 9:34 PM
{type: 'SETHEALTH', payload: {person: 'sam', health: 0}}
that would be a valid action correct @vcarl ?
vcarl - Today at 9:35 PM
yes, but!
❤1
BTM - Today at 9:35 PM
Like https://github.com/contra/react-responsive (not updated for some time though)
GitHub
contra/react-responsive
react-responsive - Media queries in react for responsive design
vcarl - Today at 9:35 PM
that's a subtle antipattern, because then you're effectively making a function call with more ceremony
catmando - Today at 9:35 PM
my point exactly
vcarl - Today at 9:35 PM
the actions should describe intent, not implementation
jsonnull - Today at 9:35 PM
Your action should have as little domain-specific knowledge as possible.
vcarl - Today at 9:35 PM
you don't get it for free, but actions enable it
catmando - Today at 9:36 PM
so it seems to me that its just a matter of good protocol design
timboslive - Today at 9:37 PM
thanks BTM, I think thats essentially what im after (hide/move sidebard on small screens)
vcarl - Today at 9:37 PM
i'd say part of the argument is that flux has fewer footguns than MVC, and the ceiling for good design is higher
it's still possible to write incomprehensible spaghetti that's tightly coupled with flux/redux, but you can also write really elegant code
whereas most MVCs devolve into spaghetti beyond a certain scale
BTM - Today at 9:37 PM
@timboslive you can do that with just using media queries in CSS though, this one is usefull when you want to skip rendering the component altogether (because for example it has expensive calculations in its lifecycle)
vcarl - Today at 9:38 PM
or hey, maybe everyone's wrong! maybe it's spaghetti all the way down and flux is just the newest fad ¯_(ツ)_/¯
flux didn't come from the heavens heralded as The Right Way, facebook just described it and said "hey we've had pretty good results with this"
and everyone has bickered over details for 2 years
catmando - Today at 9:39 PM
right
but what I see happening (as an outsider) is that you don't find the detailed understanding you have given me
basically if you read most of what is out there it says hey
you make these actions
timboslive - Today at 9:40 PM
I am using material ui which has inline styles, my understanding was I cant use media queries?
catmando - Today at 9:40 PM
and you dispatch them and POW you have the great flux loop.
Welll
as I just proved I can easily create an action that leads to brittle code
vcarl - Today at 9:40 PM
well that's just the typical blogspam that's 80% right and misses the beauty beneath it
jsonnull - Today at 9:40 PM
You can't use inline media queries on html elements, but you can add a class to it and add a media query for that class the "old fashioned way"
@timboslive ^
BTM - Today at 9:40 PM
on https://discordapp.com/channels/102860784329052160/102860784329052160
@timboslive but you can still attach a static CSS to the bundle (and have webpack process it) or link it from the HTML file that will embed the app
vcarl - Today at 9:40 PM
that happens to everything
catmando - Today at 9:41 PM
sure no criticsm of flux... I wouldn't be here, if there wasn't some value
hey, gotta go, but you guys have been a huge help. thanks so much!
❤1
NEW MESSAGES
vcarl - Today at 9:41 PM
i do think part of it is that i got in "on the ground floor" and have had the luxury of following the developments as they've happened, in real time. i didn't have to google for stuff and end up finding shitty articles with good SEO, i watched the talks as they came out
yy1
watch dan abramov's talks, chenglou's talks, ryan florence, michael jackson
there are a few really big names who did a lot for refining concepts and putting together informative articles
oh and jlongster
@catmando Imho, think about actions like they are military orders, commander says 'attack this ship', and if chain of command is organized, everyone (reducer, thunk, saga) knows what to do when they hear it. But at the same time order can be too specific(like 'private Rayan go few 5 steps left, open the door, go 50 steps till you see a toilet on the right') or chain of command can be too long or broken and everybody dies.
vcarl - Today at 9:55 PM
Last comment: I don't think Flux patterns are a panacea for app development. You could implement the idea with MVC and end up with all the same benefits, just some extra overhead. It still boils down to needing to out thought into how different parts of the app communicate. Flux just provides some guidelines about how to think about it, and the best/common practices are different than what MVC endorses/enables
timboslive - Today at 9:56 PM
@BTM, thanks