wcjohnson / redux-components Goto Github PK
View Code? Open in Web Editor NEWA component model for Redux state trees.
Home Page: https://wcjohnson.github.io/redux-components
License: MIT License
A component model for Redux state trees.
Home Page: https://wcjohnson.github.io/redux-components
License: MIT License
CS2 converts interpolated strings into ES2015 interpolated strings. Add the babel transform to the toolchain to generate ES5 compliant code.
Split from #4
There's no way to do this without creating state that's not a part of the store, because fundamentally, a reducer is a function and a function can't be state.
However, as you pointed out, if the state that's not a part of the store is a pure function of the state that is, and we can guarantee it gets synced with the store, that should still be OK.
So here are my thoughts right now:
getReducer()
is now passed the local state
as an argument. When first mounting, this will be the initial state. So:getReducer: (state) => (state,action) => nextState
A new action symbol, @@REPLACE_REDUCER
, will be added.
The actual reducer produced by Redux Components internally, the one that really gets mounted to the state tree, will be a closure that has an additional layer of indirection, and when it gets the @@REPLACE_REDUCER
action, it will hot swap the "real" reducer by calling getReducer()
.
Advantages:
DOES NOT require the root store to rebuild its reducer!
State, in toto, is still a pure function of Redux state. getReducer()
is only receiving information that already is in the store.
This doesn't just enable the thing we're talking about here, but a huge range of behaviors where reducers can depend purely on state.
Disadvantages:
Appears to absolutely require impurity in the intermediate layer of reducer indirection. How do we respond to @@REPLACE_REDUCER
purely?
Performance hit of one extra nested function call for each layer of Redux state tree depth. (Won't matter when JS finally implements proper tailcalls -- probably won't matter before that, even.)
Things that need to be tested intensively:
Store initialization and rehydration situations
TIME TRAVEL
redux-components enables and encourages designs where components are built up from simpler ones as sub-branches using SubtreeMixin
. In practice we've found that this can leave one with subtrees that may be a few levels deep, whose leaves are just a bunch of ObjectStore
s.
This kind of design can lead to a single action creator on a high branch firing multiple action creators on a subbranch, and so on down the tree until you get a quite large sequence of primitive actions reducing over all the ObjectStore
leaves simultaneously, thus tripping a lot of Redux store updates.
We have been doing several things internally to mitigate this phenomenon:
NB: Don't prematurely optimize! Make sure this is actually a problem for you before using these remedies. For many use cases, there won't be a noticeable impact.
I don't particularly like that we have to resort to the country doctor remedy, so I'm looking for feedback here. Early days but my own instincts tell me we need something like redux-batched-actions that can be mixed in at the top of deep subtrees that will (somehow) automatically compose the actions.
@action({withDispatcher: otherFunction})
, @selector({isScoped: false})
Components that are strictly specified by a combineReducer subtree. (No actions, verbs, selectors, or utility methods.)
This could be useful to declaratively specify a structure for a component that encapsulates complex internal data using the SubtreeMixin.
There is no test for this in the suite, and it wasn't working in 4.3, which is a source of downstream failures in components that rely on this feature.
Now that CoffeeScript 2.0 is available, and we're on the Babel toolchain, we can deliver proper support for ES6 classes by analogy with the react model. Something like:
class MyComponent extends ReduxComponent
# construction
constructor: -> super
# reducer
getReducer: -> (state={}, action) -> state
# lifecycle
componentWillMount: ->
componentDidMount: ->
componentWillUnmount: ->
Problems will arise (as they do with React) in things like magic-binding functions. We will also need an API for doing the magic we do with selectors and actionCreators right now.
Document a use case where the root reducer is not managed by redux-components. Add unit tests as well.
Currently the subtree mixin allows you to have a predetermined component structure, which remains static throughout the application lifetime. This directly maps onto the redux combineReducers
function.
It would be possible to implement a new combinator, say combineReducersMap
, which as well as delegating actions to sub-reducers, also implements ADD
and REMOVE
actions itself. These actions would allow dynamically changing the set of child components and reducers.
The sequence of actions would be:
ADD
action received, with a key and component typeThis could then be encapsulated inside a Map
component, which implements add and remove action creators.
Unfortunately it would be difficult to do the same thing for a List
type, since the way this is currently built, each component is aware of its full path, and so it would be difficult to update all of the paths. Maybe with a componentMove
event or similar, it would be possible...
The motivation is to be able to dynamically change the layout of stores - for example, you might have allow logging into multiple accounts at the same time, like google does, in which case you can put the vast majority of your application state inside a component which gets instantiated once per logged-in account.
In large builds, multiple packages may depend on redux-components. This can cause duplicate copies to end up in a webpack bundle.
This, in turn, causes multiple instances of key objects like the ReduxComponent base class, which causes instanceof()
to fail to properly detect ReduxComponents that come from another copy of the library.
The ultimate manifestation of this is cannot mount something that isn't an instance of ReduxComponent
errors in dev invariant mode.
We should consider storing critical information on a global object, or perhaps using something like React 15's $$typeof symbol.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.