-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
Add react-is package #12199
Add react-is package #12199
Conversation
I'm personally not a big fan of the Another plausible approach is that we expose the symbols and Then you can switch on symbols instead of strings: switch (typeOf(node)) {
case ReactIs.Element:
...
case ReactIs.Fragment:
...
} |
Wouldn't the issue still remain that we'd have to access the symbols from a different attribute/path depending on the type of element (e.g. Sorry if I'm missing or misinterpreting something. |
The implementation of typeOf would work exactly the same. It would just return symbols as the return value instead of strings. I don’t know if I can really motivate this very strongly though. Just feels more specific with symbols since they don’t take up string space but in practice strings are probably fine and more practical. |
Oh, I see. I misunderstood your initial suggestion 😄 So you're saying rather than someone using e.g. import React from 'react';
import ReactIs from 'react-is';
const ThemeContext = React.createContext('blue');
ReactIs.isContextConsumer(<ThemeContext.Consumer />);
ReactIs.isContextProvider(<ThemeContext.Provider />); They would use: import React from 'react';
import ReactIs from 'react-is';
const ThemeContext = React.createContext('blue');
ReactIs.typeOf(<ThemeContext.Provider />) === ReactIs.ContextProvider;
ReactIs.typeOf(<ThemeContext.Consumer />) === ReactIs.ContextConsumer; I guess we'd still have to export the numeric fallback values for environments that don't support I'm not opposed to making this small change, if that's what's required for this lib to be shippable. 😄 |
I think using isContextConsumer is still best practice when you only test for a single value. The typeOf is more about logging and switch statements where there are many possibly legit options. We stopped using isValidElement internally for the benefit of switch statements so seems like others might want to too. Although strings support that case too. |
Cool. Seems like exporting constants for the string return-types would satisfy the switch/case use case as well. I don't really have a strong preference. Gimme a few and I'll push an update. 😄 |
Can be used without any dependency on React. Plausible replacement for React.isValidElement.
Okedoke. Rebased and added symbol exports. |
packages/react-is/index.js
Outdated
|
||
// TODO: decide on the top-level export form. | ||
// This is hacky but makes it work with both Rollup and Jest. | ||
module.exports = ReactIs.default ? ReactIs.default : ReactIs; |
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.
We should do this correctly right away since it's not a legacy package.
Let's remove the default export here and only provide named exports. That's how we make it work with tree shaking, too (when we provide an ES build output).
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.
To clarify, I'm saying this file shouldn't need to use CommonJS at all. Just re-export *
from the source.
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.
Hm. Okay.
I'm curious: Why didn't we follow that pattern with other new packages (like react-reconciler
)?
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 there was some reason but I don't remember straight away.
It's not very important in case of the reconciler though because it provides just one function. react-is
, on the other hand, provides a bunch, and is expected to grow.
Call/Return does avoid the .default
hack:
react/packages/react-call-return/index.js
Line 12 in 29e8924
module.exports = require('./src/ReactCallReturn'); |
If there's some issue with top-level ES import (maybe there was) then the above is sufficient.
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.
Okay. This makes sense. Thanks for the suggestion. 😄
It's been updated.
It looks like the Rollup build checks report an ESLint failure from the UMD builds:
The line in question is: typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : I believe we could fix the lint error (without breaking the UMD build) by changing the signature to: typeof module === 'object' && typeof module.exports === 'object' ? factory(module.exports) : But I'm not sure how to achieve this within the context of Rollup. 😄 I'm going to just remove the UMD build from the bundle. I added it because it seemed like a nice to have, but I don't think it's really very useful. |
Authoritative brand checking library. Can be used without any dependency on React. Plausible replacement for `React.isValidElement.`
@bvaughn |
Unknown. Have a minimal repro? |
Seems expected to me, #4832 didn't land until 0.14 so we didn't have |
Ah, thanks Dan! I'm not really familiar with React 13 or 14 😅 |
Lucky you! |
@gaearon in 0.13, isValidElement was https://github.com/facebook/react/blob/v0.13.3/src/classic/element/ReactElement.js#L290-L302 - if i made the tiny PR required to fall back to checking My hope is to migrate the final enzyme adapter using |
It's an extra property lookup for a thing that isn't there (for cases when we normally return false), so I don't think we'll want to do this. |
What if I came up with a way to determine if $$typeof was present or not at require time, so there'd be no runtime cost? |
I don't know if we've articulated whether this package has any versioning guarantees. In particular I'd like to preserve the option to use an |
@sebmarkbage currently it works on 0.14, 15, and 16, fwiw. As far as extensibility - that's exactly why i want to use I don't anticipate "0.13 support on isElement" to add more than a line or two, fwiw. |
Supersedes PR #11279 and #12092. Resolves issue #12038
Perhaps we could use this in React DevTools as well?(This would not be the case in its current form, since this library accepts React elements and DevTools receives fibers.)Tests
In addition to the newly-added unit tests, I ran
yarn build react-is
locally to build this, thennpm pack
ed the result and installed it in a fresh project. I also tested the UMD build in CodeSandbox.Example
Assumptions
isElement
is looser thantypeOf
(e.g. it returns true for host elements, fragments, strict-mode, context, etc.)AsyncMode
for the initial release.