-
Notifications
You must be signed in to change notification settings - Fork 47.6k
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
Resolve flow errors with ReactTestRenderer #7736
Conversation
|
||
type ReactTestRendererJSON = { | ||
type: string, | ||
props: { [propName: string]: string }, | ||
children: Array<string | ReactTestRendererJSON>, | ||
children: null | Array<string | ReactTestRendererJSON>, | ||
$$typeof?: any |
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.
Flow kept giving me a warning about $$typeof
if I didn't mark it as optional. I think it might be because we're using Object.defineProperty
?
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.
This is weird :(
@@ -15,6 +15,7 @@ | |||
import type { ReactText } from 'ReactTypes'; | |||
|
|||
class ReactTestTextComponent { | |||
_currentElement: ReactText; |
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.
Not sure if we've been doing it consistently, but it would be good to give a bit of whitespace between types and actual JS - can you just put a newline under here (and in the other class too)
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.
Yupp, of course 👍
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.
@zpao I added the second class
usage in the codebase last week, so it's probably consistent so far :p
children: Object, | ||
transaction: ReactTestReconcileTransaction, | ||
context: Object, | ||
) => void; |
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.
These methods are inherited from ReactMultiChild. Is there a way tell flow that this class inherits from ReactMultiChild using the current method of calling Object.assign
on the prototype? ReactMultiChild isn't typed yet, though.
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.
There isn't. In this case, since there's only one Object.assign, could you replace with class ... extends ReactMultiChild
which flow should understand
children: Object, | ||
transaction: ReactTestReconcileTransaction, | ||
context: Object, | ||
) => void; |
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.
There isn't. In this case, since there's only one Object.assign, could you replace with class ... extends ReactMultiChild
which flow should understand
|
||
type ReactTestRendererJSON = { | ||
type: string, | ||
props: { [propName: string]: string }, | ||
children: Array<string | ReactTestRendererJSON>, | ||
children: null | Array<string | ReactTestRendererJSON>, | ||
$$typeof?: any |
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.
This is weird :(
type TestRendererOptions = { | ||
createNodeMock: (element: ReactElement) => Object, | ||
export type TestRendererOptions = { | ||
createNodeMock: (element: ReactElement<any>) => Object, |
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.
Can you put and remove <any>
import { ReactElement } from 'ReactElementType';
We're trying to use the internal type (and not the one provided by flow) inside of the codebase
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.
Please change Object
to either any
, mixed
or the proper type.
The problem with using Object
is that it makes it look like it is flow typed but in practice flow doesn't know any of its attributes so it cannot verify anything about it.
We're trying to either have the correct type or mixed
(and if mixed
doesn't work then any
)
@@ -15,6 +15,7 @@ | |||
import type { ReactText } from 'ReactTypes'; | |||
|
|||
class ReactTestTextComponent { | |||
_currentElement: ReactText; |
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.
@zpao I added the second class
usage in the codebase last week, so it's probably consistent so far :p
class ReactTestComponent { | ||
class ReactTestComponent extends ReactMultiChild { | ||
_currentElement: ReactElement; | ||
_renderedChildren: null | Object; |
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.
any
Looks like there's a test failing. Probably related to turning the Object.assign inheritance to extend :x |
@vjeux looks like it's because I can either revert to using |
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.
Sgtm, can you npm run build on both master and this to see the impact on file size?
@vjeux it does increase the build size a bit
I'd be happy to roll back the |
|
Shipit :) |
@@ -93,7 +93,7 @@ function injectAfter(parentNode, referenceNode, node) { | |||
|
|||
// ContainerMixin for components that can hold ART nodes | |||
|
|||
const ContainerMixin = assign({}, ReactMultiChild, { | |||
const ContainerMixin = assign({}, ReactMultiChild.prototype, { | |||
|
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.
Is this a breaking change for ART?
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 shouldn't be AFAIK, it's still extending the same methods. They just exist on a class now instead of an object.
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.
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.
In other words ART relies on private APIs (MultiChild), and private APIs just changed in this PR. Same for React Native until it starts using its own renderer copy (I think this hasn't happened yet).
Maybe I got it wrong but I think this is a breaking change for ART and RN and I'm not sure what we should do next.
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.
Thanks for explaining that, in that case it looks like this would be a breaking change. I can open PRs in RN and ART to update their use of MultiChild. Though I don't see and use of ReactMultiChild
in RN
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'm probably missing something obvious, but why would it? That doesn't touch ReactART or ReactMultiChild.
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.
This fixes flow errors introduced by #7649, so I was just wondering if we'd cut a release that contained some flow errors.
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.
Oh. I don't think that's terrible if we're confident that there are no bugs. But we should definitely find a way to fix flow errors before v16 since that isn't immediately coming. Maybe we can just remove flow from ReactTestRenderer or add some suppression comments for now if ReactMultiChild needs to be a class like this?
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.
The issue was that flow didn't understand that ReactTestComponent was inheriting mountChildren
and updateChildren
from ReactMultiChild with Object.assign
.
One way around that is what I did initially, which is just add annotations for those methods on ReactTestComponent directly. A suppression would work too. I'd be happy to revert the class conversion and fix the flow error somehow else.
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.
Let's do that for now please. Thanks for following up. :)
Where did we end up on this shipping & react-art? I'm cherry-picking this into 15.4 and will ship in RC unless I hear otherwise. |
As long as you pick #7757 too we're good. |
That brings us back to the state post- #7598, which was semver-major. Presumably we need to get back to |
Resolves #7735