reduxjs/redux-devtools

Challenge: Implement a cool custom monitor

gaearon opened this issue ยท 23 comments

<DevTools> accepts a monitor prop. The monitor that ships with react-devtools is called LogMonitor but it's just a React component. You can build your own instead.

I challenge you to implement a really different monitor than what we ship with. Some crazy ideas:

  • A slider that lets you jump between computed states just by dragging it
  • An in-app layer that shows the last N states right in the app (e.g. for animation)
  • A time machine like interface where the last N states of your app reside on different Z layers

LogMonitor propTypes should give you some ideas about the stuff injected by DevTools:

static propTypes = {
  // Stuff you can use
  computedStates: PropTypes.array.isRequired,
  currentStateIndex: PropTypes.number.isRequired,
  stagedActions: PropTypes.array.isRequired,
  skippedActions: PropTypes.object.isRequired,

  // Stuff you can do
  reset: PropTypes.func.isRequired,
  commit: PropTypes.func.isRequired,
  rollback: PropTypes.func.isRequired,
  sweep: PropTypes.func.isRequired,
  toggleAction: PropTypes.func.isRequired, // ({ index })
  jumpToState: PropTypes.func.isRequired // ({ index })
}

This data (and functions) will be injected into your monitor by the dev tools. Feel free to use (or ignore) any of them, and let me know if something important you need for a custom monitor is missing.

This example commit is a good starting point for adding DevTools to your React project: 0a2a975. (Nevermind the Webpack config changes.)

To work on a custom monitor, you can remove DebugPanel and LogMonitor completely and instead use <DevTools store={store} monitor={MyCustomMonitor}>.

To make it easier to build a slider-like monitor, I added two new props to the monitor contract: jumpToState({ index }) and currentStateIndex. Use them to implement slider time travel interface without extra hassle.

One thing I would find really helpful in the default LogMonitor is a shortcut to show/hide the dev tools. Something like ctrl+opt+h maybe. If you like the idea, I can make a PR.

hzoo commented

@pburtchaell I think that would be cool! Since chrome's is f12 - maybe there's a shorter keyboard shortcut? (or there's some kind of config for it)

@pburtchaell +1 I think PR would be great, this is must have feature

I am sure that it is more important not to enhance this monitor, rather than make an interface for plugins to "rule them all"(hiding with some hot key should be a part of it of coarse). I have struggled with some style issues when I add another panel here so I implemented some really dirty hack component. But it should not be like that, and this is not plugin responsibility. Devs should be able to add new plugins transparently to redux-devtools. If it will be like that there will be a boost of growth. I also wrote about it here.

I created something similar: http://jorin.me/miniflux/#update-time-travel
Unfortunately it's not Redux but maybe it helps as inspiration with the preview on hover feature.
Should be pretty simple to port.

I'm going to be busy in the next couple of weeks with shipping Redux 1.0 so feel free to experiment while I'm away!

@jorin-vogel really nice thing! ๐Ÿ‘ for porting.

Oh that's very neat! I'd love to see that ported!

Stealing the gif for inspiration:

Alright, I have it setup to show/hide when you press crl+h. I'll send in a PR this morning.

redux-devtools

PR sent in #12.

@gaearon I wanted to create a slider for Atom-React but never had the time to work on that.

Anyway, just wondering if you record timestamps of action publication time? This would be useful to implement user session recording like I did here: https://www.youtube.com/watch?v=zxN8FYYBcrI

Having a slider is already nice, but I thought it would be even cooler to have a VLC like player :)

I was also considering recording some "side effects" like window resize, scroll position, mouse position, mouse clicks. Would be cool to be able to view the mouse position over time during replay.

Anyway, just wondering if you record timestamps of action publication time? This would be useful to implement user session recording like I did here: https://www.youtube.com/watch?v=zxN8FYYBcrI

Not currently but it's a neat idea. Happy to add it (should be easy by tweaking PERFORM_ACTION handler in devTools.js).

Took a quick stab at the slider here, using react-slider. I just shoved the slider into the existing LogMonitor and tried it out in the examples (just npm install in each of the examples). It's very very rough, but already feels magical jumping between states. I'll try to break it out into its own repo if anyone's interested.

Please make it into a repo!!

Done! redux-slider-monitor. I thought it'd be fun to make it kind of look like a video player. If you get timestamps into actions we can make it replay actions in real time! ๐Ÿ˜ƒ

cool :)

@calesce once @gaearon add timestamps, maybe you can take a look at my code here:
https://github.com/stample/atom-react/blob/master/src/atomReactContext.js#L447

It's the very basic implementation of "replay" in my own framework as shawn in the video (https://www.youtube.com/watch?v=zxN8FYYBcrI). Not sure at all it's a good solution, just showing you what I did as a poc :)

@calesce great work! =)

@slorber nice! Why did you use tickPlace = 10? I guess 1 would be overkill?

I imagined I would eventually use something like requestAnimationFrame and just use the difference in timestamps between actions to get the time to jump to the next state (if that makes sense, not sure if it's proper use of requestAnimationFrame). Your solution definitely works, though.

@calesce this is just a random tick value for my poc but I guess requestAnimationFrame could work very well too.

Yes using time from start or time from previous action, both will work fine. I had to choose one but I think time from start is better as anyway to have to compute it if you want to tell the user how much time is elapsed/remaining in the video.

Once the video is recorded, does working with the original timestamp really matter? What the user wants is to see the video and I think it does not make much sense to keep the burden of working with timestamps because nobody cares so much of the time at which a video frame was taken while watching a video, it does not bring us any useful information imho.

Since then, the API has changed. Take a look at LogMonitor props to get a better idea. Monitors also have to export an update static property which should be a function (monitorProps, monitorState, monitorAction) => monitorState. It must exist even if it always returns undefined.

I'll close the issue for inactivity.