-
Notifications
You must be signed in to change notification settings - Fork 1.8k
[WIP] Support hiding components in devtools #1187
Conversation
If they checked by default - that is breakable change
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need the corporate CLA signed. If you have received this in error or have any questions, please contact us at [email protected]. Thanks! |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
Call in the discussion of interested persons |
Looks good to me! I'm no longer a committer on this project, so I'll have to let someone else merge |
I'm not sure how I feel about the hidden symbol. I don't like the |
backend/attachRendererFiber.js
Outdated
@@ -176,6 +178,8 @@ function attachRendererFiber(hook: Hook, rid: string, renderer: ReactRenderer): | |||
publicInstance = fiber.stateNode; | |||
props = fiber.memoizedProps; | |||
state = fiber.memoizedState; | |||
hideSymbol = typeof Symbol === 'function' && fiber.type[Symbol.for('react.devtools.hide')]; | |||
hideDisplayNamed = fiber.type.hasOwnProperty('displayName'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I'm jet lagged at the moment so maybe this is a stupid question, but why is the "displayName" check here? I don't get how it's related.
frontend/Breadcrumb.js
Outdated
@@ -163,7 +163,7 @@ function getBreadcrumbPath(store: Store): BreadcrumbPath { | |||
} | |||
|
|||
module.exports = decorate({ | |||
listeners: () => ['breadcrumbHead', 'selected'], | |||
listeners: () => ['breadcrumbHead', 'selected', 'hideSymbol', 'hideDisplayNamed'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is Breadcrumb
listening for hideDisplayNamed
and hideSymbol
when it doesn't use them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's used in getBreadcrumbPath
> store.skipWrapper
frontend/PreferencesPanel.js
Outdated
checked={hideDisplayNamed} | ||
onChange={this._changeHideDisplayNamed} | ||
/> | ||
Hide components with custom <code>displayName</code> property |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why you'd want this particular functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many HOC's creates wrapper components with custom displayName like SomeWrapper(OriginalComponent)
In contrast, regular components usually do not use dispalyName
I thought that such a simple rule is suitable for a draft, and better than nothing
This is the minimum that I would like to get in order to hide noisy HOC's
I can add/replace with other simple HOC recognition, if they work better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many HOC's creates wrapper components with custom displayName
In contrast, regular components usually do not use dispalyName
There are many that are kind of like "presentation HOC" and assign displayName through babel plugin, i.e styled-components, emotion, jss, etc:
const MyButton = styled.button`
color: tomato;
`
// MyButton will have displayName: "MyButton" crafted by babel plugin
Although they are technically HOC i'd not want to hide them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the displayName
attribute is too likely to cause false positives, as @asvetliakov points out, due to popular plug-ins like babel-plugin-transform-react-display-name
. It also feels too arbitrary to me.
backend/attachRendererFiber.js
Outdated
@@ -176,6 +178,8 @@ function attachRendererFiber(hook: Hook, rid: string, renderer: ReactRenderer): | |||
publicInstance = fiber.stateNode; | |||
props = fiber.memoizedProps; | |||
state = fiber.memoizedState; | |||
hideSymbol = typeof Symbol === 'function' && fiber.type[Symbol.for('react.devtools.hide')]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: react-devtools.hide
?
I find the method discussed in #676 more appealing.
For hiding that is, not dimming. Could also have a checkbox in devtools to enable/disable the feature (or maybe even toggle between hiding and dimming). |
I believe I would also be more of a fan of that approach, as it would be more consistent with filtering other categories of components (as described in #1076) |
- correct merge with default value from Store - need call handler for changes emited at another handler
…vtools.hide # Conflicts: # backend/attachRendererFiber.js
This was so good looking until it wasn't. Would you please remove the second approach with |
@Gvozd thanks, much better. I am wondering, won't this symbol approach be somewhat problematic in TypeScript or possibly even Flow? Generally attaching foreign properties to objects is rather painful with static typing. Any ideas how it could be solved except using |
I wasn't thinking of attaching it to arbitrary functions but rather to functions/classes you generate yourself as part of the HOC factory function. |
Well, for an example I would like to hide all const context = React.createContext()
// @ts-ignore
context.Consumer[hideSymbol] = true This is especially troubling for 3rd party ones. And also some stateless components are useless to be visible in the tree, so that's about attaching a symbol to the existing function. |
use-case: - one of hiding checkbox is enabled - open full tree of HigherOrderComponent(Nested) - toggle another checkbox. TreeView is not changed(because HOC hided by another checkbox) Changed timings for `wrapMultipleNested(Nested, 25/50/100)` ms: 413/1170/4044 -> 54/94/184 O: O(n^2) -> O(n)
|
I am thinking this is not needed as much anymore by introducing React Hooks. It's obvious that need for HOC and various middle-man components will be gone with this and we will have a naturally clean component tree 🎉 |
The old HOCs will not disappear anywhere for a long time It also takes time
This is the case if all developers accept hooks as more convenient, and decide to switch to them in full So I think that to hide the HOCis still necessary and useful. |
…vtools.hide # Conflicts: # frontend/Store.js
I think I need to leave only one option of hiding/dimming, for the HOC with parentheses in the name |
I think dimming should be the default. A toggle to hide instead would be usefull.
Good idea. |
I don't think the dimming is very useful. It's very subtle and the tree is just as cluttered as before. (I think the primary purpose of hiding components is that the element tree is too crowded.) I also think it's confusing to have a checkbox that says, e.g. "Hide HOCs..." when they won't actually be hidden unless you select one of three radio options above. I suppose I could imagine a UX where we have a global toggle on/off, but I don't think it's necessary. I realize this PR has been pretty long running, and I feel bad about the inconvenience. If you'd like, I could pick up where this PR leaves off and make the additions I had planned for #1076 originally? |
@bvaughn, OK. |
I personally appreciate a dimming option for HOCs, as they are part of the virtual DOM and I'd like to view them as such, but at the same time want them to be visually distinguishable/faded since they are HOCs / less impactful than regular components.
We just talked about this and I agree that the radio buttons are inconvenient. My suggestion was to make a checkbox/toggle for hiding. If dimming gets included in this feature then it could be the off-state of said toggle. |
Add two options for hiding components
[Symbol.for('react.devtools.hide')] = true
- rebase of PR Support hiding components in devtools with Symbol.for('react.devtools.hide') #997displayName
- I think that most popular case for HOCI'm waiting for feedbacks
It is time to move forward on this issue after long discussions.