Skip to content
This repository was archived by the owner on Oct 19, 2018. It is now read-only.

chat about flux on discord

Mitch VanDuyn edited this page Jan 25, 2017 · 2 revisions

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

Clone this wiki locally