-
Notifications
You must be signed in to change notification settings - Fork 18
chat about flux on discord
catmando - Today at 8:47 PM hi is this right place to ask a basic question about the flux architecture? Sebastian_Grillo - Today at 8:47 PM awesome 😄 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: https://cdn.infoq.com/statics_s1_20170124-0303/resource/news/2014/05/facebook-mvc-flux/en/resources/flux-react-mvc.png
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 https://cdn.infoq.com/statics_s1_20170124-0303/resource/news/2014/05/facebook-mvc-flux/en/resources/flux-react.png
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 :smiley: 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 ezequielwards - Today at 9:18 PM hey, is there a channel for beginner on react ? catmando - Today at 9:18 PM method = KILL / Sam.setAlive vcarl - Today at 9:18 PM #need-help 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 :smiley: 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 :smiley: 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
ezequielwards - Today at 9:22 PM Hey @vcarl this is the channe for Q&A #need-help ? vcarl - Today at 9:22 PM @catmando, lemme phrase it differently no this is general, click the link acemarke - Today at 9:23 PM @ezequielwards : ahh... no, this is #general. Click on that blue "need-help" ezequielwards - Today at 9:23 PM Ok, Thanks @acemarke 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 designvcarl - 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