-
Notifications
You must be signed in to change notification settings - Fork 674
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Middleware for debugging? #71
Comments
This looks neat, thanks for the write-up. I've not seen anything similar. Seems like it might be a neat thing to somehow have in a |
I'm also interested in debugging middleware. The fancy graph @MattSPalmer put together would be cool, but I'd start even simpler - logging the memoized values to the console, similar to how redux-logger does on every action. We could do it every action, or only when the memoized value changes. This would be very useful for me because I use the memoized values in my view layer and I need to be able to check that they are what I think they are when debugging. I started doing something like this in our application. I'm not sure if it makes sense to include middleware in reselect or package it separately, but I'd be happy to share it if desired. |
I would be interested to see your approach, @aarongreenwald. I'm also not sure if building middleware capabilities into reselect is the way to go. I do think that without middleware, anything beyond logging memoization behavior will be difficult. As far as inspecting memoized values, I've had some luck with using a special memoization function that has logging side-effects. |
Here's what I have for now const reselectLogger = (selector, name) => ({getState}) => next => action => {
let oldState = selector(getState());
let result = next(action);
let newState = selector(getState());
if (oldState !== newState) {
console.log(`Selector recalculated: ${name}`, selector(getState()));
}
return result;
}; and then let middlewares = [
...
reselectLogger(someSelector, 'Selector Name'),
reselectLogger(anotherSelector, 'Another Selector Name'),
];
const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore);
const store = createStoreWithMiddleware(rootReducer); When I get around to it, I'll improve the console.log statement to format the output nicely so that it fits in with the redux-logger output. Also, I'd like to figure out a way to avoid having to include an instance of the middleware for every selector I have. I have some ideas but I think they're overcomplicated. |
You could use a custom memoize function - that would allow you log every selector state change which would be quite cool. https://github.com/rackt/reselect/blob/master/src/index.js#L5 |
Hmmm. I also would like to know when a selector is recalculated. Your middleware @aarongreenwald seems to verbose to setup though. Maybe @MattSPalmer can share some infos about that custom memoization function? |
https://gist.github.com/kbrownlees/93e57729d6ad95f38381/02771956d0ba3f16ca6333b8983af012f55d9695 It works but it hard to read when you have lots of selectors! I did make it so you can do something along the lines of: createSelector('my awesome selector', selector1, (s1) => s1) This prepends all the logs with 'my awesome selector', but I am not convinced on this strategy and haven't had much time to spend on it lately (I did have dreams of integrating it with redux devtools so you could see the action -> selectors flow). It would probably be better if it allowed things to subscribe to changes and provided all the information (old / new inputs and old / new results) rather than just logging the new result. EDIT: Changed the gist so it now uses a memoize which makes a callback when something changes: https://gist.github.com/kbrownlees/93e57729d6ad95f38381 |
Inspired by reduxjs/reselect#71, a memoize function which will perform a callback everytime the result changes.
@kbrownlees Your module looks interesting. I'm going to close this out and suggest that people check out your library. |
Hi there team. Really enjoy the library.
Was wondering if there's been any consideration thus far for introspection into one's selectors via middleware or some other modification? As apps grow bigger and selectors increase in complexity, I can see a lot of value in having some way to quickly (and visually) trace the origination of an arbitrary selector's value.
All selectors created by
createSelector
can be described as having X 'ancestors' and Y 'descendants'. Seems to me these relationships lend themselves really well to being represented as a visual hierarchy; a tree, graph, or what have you.Consider the example in the README:
One could conceive of a graph showing the flow of state down through to totalSelector:
Nodes on such a graph could contain information such as the number of re-computations on that selector, the last memoized value, when the value last changed, etc.
Curious to know if there's interest in a project that would generate output like the above, or if someone's done similar work already. Either way, I'd love to help out!
The text was updated successfully, but these errors were encountered: