-
Notifications
You must be signed in to change notification settings - Fork 46.9k
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
RFC: Initial outline for new devtools api #5462
Conversation
@sebmarkbage has context on this. cc @spicyj for reference. |
0f114f5
to
10e1289
Compare
In general, I like this. I have a question: how does this design deal with attaching mid-way? For example, say there's an async dev tool that only connects to a page after some initialization period. Or say it allows reconnecting. (I believe React DevTools currently let you do this?) If a devtool derives all of its internal state from an event log, if it misses the start of the event log and connects asynchronously, it can't derive the state. However keeping a reference to the event log is also wasteful. Am I overthinking this? |
Another question is whether the DevTools API is meant to be completely read-only.
Forcing re-render is a big use case for me. (Especially so for the functional components that don't even have an instance to call |
@gaearon Forcing rerender is easy - you will already know the React root's "container" node (from the previous render events your devtool witnessed) and you will already have the element that was rendered to that node (from that same previous render event), so you can just invoke Regarding read only: This API is intended to provide one side of the CQRS flow. Specifically, this API handles QUERY (all data that React provides will come in the form of these events). It does not provide the command side/flow, which is completely independent by definition of CQRS. For now, the command side would require utilizing the existing public API (or reaching into internal/private API) until such time as we can design+expose an intelligent set of commands for devtools. |
How do you plan to deal with functional components? They don't have (public) instances, but dev tools may need to re-render them or at least show them in a tree. Do they have IDs but not instances? Do dev tools receive internal instances? |
@gaearon That question is slightly orthogonal to this API (it's a matter of what is doable in the React core, regardless of the communication mechanism). That said, functional components will not have internal instances and so there is no way to reference/rerender only a functional component. You would need to rerender the closest parent ancestor. |
I was curious what your thoughts on these are, as in an app made purely with functional components (extreme but entirely possible case), there isn't a single instance one could re-render. But I agree it's orthogonal so let's discuss later when there are more specifics. |
Merged in #5590. |
@jimfb sorry for the late comments on this. Unless I am mistaken, this api only works in dev right? But what if you want to have your devtools work in production for debugging purposes? |
Example use case: I am working on an e2e testing library that would want to use this api for performing assertions, however due to the nature of e2e you don't want to restrict yourself to only testing dev builds |
@oliverwoodings Correct, dev only. FWIW, due to the nature of e2e tests you only want to test user visible behaviors. You shouldn't need a devtool (which is specifically for the purposes of peaking into internals) in your e2e tests, IMHO. |
Posting primarily to get feedback/thoughts/comments, and catch concerns early rather than late in the process.
The basic idea is to use a CQRS (or more specifically, Event Sourcing) pattern whereby the core will emit an event every time it does something (starts a render, ends a render, registers a dom-event-handler, resolves a ref, etc). The devtools can listen to each of these events, and derive a shadow copy of any state desired. This allows devtools to "follow along" with everything React is doing, and emit very information-full error messages, without us actually routing things through the core for the sole purpose of warnings.
Devtools are registered with React, which is global state, but is effectively what was happening before (except the current devtools uses monkeypatching, this is an explicit public API)
The "devmode" build of React (ie. the one that emits warnings) would simply be a copy of React bundled with a default devtool that registers its self with React, and keeps the necessary state to emit warnings. This means that the production and dev code paths become more similar, because the only difference is that in production
emitEvent
is a no-op.This was built with lessons learned from other tools (hot-reloading, people wanting to customize the warnings module, etc) in mind. It allows other people to build custom devtools/warnings/etc. See #5306 for details on the objectives.