JS: Model Redux and related libraries#5137
Conversation
86d732d to
c7a2975
Compare
erik-krogh
left a comment
There was a problem hiding this comment.
It looks good, but takes a while to chew through.
The order of the classes/predicates is sometimes a bit chaotic.
It's mostly RootStateSource/rootStateAccessPath, where there is a huge distance (~700 lines) between their definitions and the first use.
I have some minor comments.
| * wrapWithLogging(g); // step: g -> wrapWithLogging(g) | ||
| * ``` | ||
| */ | ||
| predicate functionForwardingStep(DataFlow::Node pred, DataFlow::Node succ) { |
There was a problem hiding this comment.
Could this be a PreCallgraphStep, instead of only being used by redux?
There was a problem hiding this comment.
Maybe as a type tracking step it would make sense, e.g. for tracking class constructors through some wrapper function. For an AdditionalFlowStep it seems a little dubious to me.
I'll run an experiment to see if anything interesting happens.
|
Thanks @erik-krogh!
Yes, sorry about that. I've shuffled things around a lot, but couldn't find a solution that didn't have this problem. |
|
LGTM. |
|
It looks like we hit the BDD node limit after the review changes 🤦 |
299b8b0 to
bccecd4
Compare
|
Updated evaluations:
|


Adds a model of the Redux library and related libraries in the Redux ecosystem, including React-Redux.
Quick overview of Redux
A Redux store consists of an initial state, a list of actions and a reducer function. The current state can always be computed by doing
actions.reduce(reducer, initialState). The only valid way to alter the current state is to append more actions to the action list. Appending such an action is called dispatching the action. The idea is that the state of the UI as a whole is derived this current state object provided by Redux.In the Redux model we are mainly concerned with two data flow steps:
Some of the complications here are:
The bulk of the model is thus to model all the ways you can do the above, in particular, handling the two primary higher-order reducers we care about: the state-delegator, and the action-delegator.
The state-delegator, commonly called
combineReducers, delegates a part of the state object to another function:The action-delegator delegates to another function based on the
action.typeproperty:Much of the abstraction comes down to handling those two cases.
Program slicing
Redux doesn't have any global state, but I decided to model it globally to avoid having to model every step of the wiring between the Redux store and an action dispatch or state access. In react-redux that would require reasoning about the nesting of JSX components all the way up to the root component, and the chance of missing a step would be too high.
To avoid false flow in monorepos containing multiple web apps, we use the enclosing
package.jsonfiles to indicate which app a given file belongs to, and thereby which Redux store it can access.React-redux
React-redux is responsible for the
connect(mapStateToProps, mapDispatchToProps)calls that tend to wrap every component in a react-redux app.mapStateToPropsprovides a way to access the current state, andmapDispatchToPropsprovides a way to dispatch actions, and in principle the model just needs to contribute these state accesses and actions dispatch calls to the abstractions set up by the main model.However, there's one place where the core Redux model has a direct dependency on the react-redux model (
ActionCreator.ref), which was to avoid a circular dependency with type tracking.Evaluations
Evaluations: (internal links)
BasicBlock.dominateschange.