- plain ol' React
let state = initial
render(view(state), element)
view
is pure!- the above +
setState
/lifecycle methods/props
/callbacks are good for simple web pages - problem - no real concept of
state
changing over time
- flux
let state = initial
let reduce = (state, action) => {}
function step(action){
// possible side effects //
state = reduce(state, action)
render(view(state), element)
}
// then call `step` on every `action`
reduce
is pure!- good for simple - intermediate apps
- assumes state is in the shape that
view
wants - no real distinction between reads/writes on the store
- it's up to the 'possible side effects' to 'decide' how to do remote syncs
- relay / om.next / falcor
the core idea is - state = model.read(view.query())
let read = (state, query, params) => {}
let mutate = (state, mutation) => {}
let remote = (query/mutation, merge) => {}
let model = ({ read, mutate, data, remote })
function step(mutation){
model.transact(mutation) // possible side effects, remote syncs
let state = model.read(view.query()) // possible remote reads
render(view(state), element)
}
read
/mutate
are pure!- in practice, you'd rarely trigger reads manually, mostly mutations. data fetching for free!
view.query()
is a simple data structure, which can be optimized, serialized, etc- we can now use the view's
query
to hold a bunch of ui 'state' we'd have otherwise saved in the store - via relay -
view
can expectstate
to be in the shape of itsquery
- can do incremental rendering based on what reads were asked, etc