Skip to content
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

Merged
merged 5 commits into from
Sep 15, 2016

Conversation

aweary
Copy link
Contributor

@aweary aweary commented Sep 14, 2016

Resolves #7735


type ReactTestRendererJSON = {
type: string,
props: { [propName: string]: string },
children: Array<string | ReactTestRendererJSON>,
children: null | Array<string | ReactTestRendererJSON>,
$$typeof?: any
Copy link
Contributor Author

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?

Copy link
Contributor

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;
Copy link
Member

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)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yupp, of course 👍

Copy link
Contributor

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;
Copy link
Contributor Author

@aweary aweary Sep 14, 2016

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.

Copy link
Contributor

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

@aweary
Copy link
Contributor Author

aweary commented Sep 14, 2016

cc @zpao @vjeux I made a first attempt at fixing what I broke :)

All flow errors should be resolved, but I'm not sure about my approach so feedback is appreciated.

@ghost ghost added the CLA Signed label Sep 14, 2016
children: Object,
transaction: ReactTestReconcileTransaction,
context: Object,
) => void;
Copy link
Contributor

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
Copy link
Contributor

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,
Copy link
Contributor

@vjeux vjeux Sep 14, 2016

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

Copy link
Contributor

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;
Copy link
Contributor

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

@ghost ghost added the CLA Signed label Sep 14, 2016
class ReactTestComponent {
class ReactTestComponent extends ReactMultiChild {
_currentElement: ReactElement;
_renderedChildren: null | Object;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any

@vjeux
Copy link
Contributor

vjeux commented Sep 15, 2016

Looks like there's a test failing. Probably related to turning the Object.assign inheritance to extend :x

@aweary
Copy link
Contributor Author

aweary commented Sep 15, 2016

@vjeux looks like it's because ReactMultiChild isn't a class or a function, so extend doesn't work. https://jsfiddle.net/enym4n2x/1/

I can either revert to using Object.assign and add the inherited types back, or I can just make ReactMultiChild a class, assuming that doesn't break lots of things :)

@ghost ghost added the CLA Signed label Sep 15, 2016
@aweary
Copy link
Contributor Author

aweary commented Sep 15, 2016

I was able to get ReactMultiChild working as a class without too much hassle, let me know if this approach is alright with you guys @vjeux @zpao

@ghost ghost added the CLA Signed label Sep 15, 2016
Copy link
Contributor

@vjeux vjeux left a 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?

@aweary
Copy link
Contributor Author

aweary commented Sep 15, 2016

@vjeux it does increase the build size a bit

   raw     gz Compared to master @ 864bc7b939ca8a93583087d1ff596cd8049b4162
     =      = build/react-dom-fiber.js
     =      = build/react-dom-fiber.min.js
  +867   +154 build/react-dom-server.js
  +303    +40 build/react-dom-server.min.js
  +867   +152 build/react-dom.js
  +304    +46 build/react-dom.min.js
     =      = build/react-with-addons.js
     =      = build/react-with-addons.min.js
     =      = build/react.js
     =      = build/react.min.js

I'd be happy to roll back the ReactMultiChild change and approach it differently if you think that would be better right now.

@ghost ghost added the CLA Signed label Sep 15, 2016
@gaearon
Copy link
Collaborator

gaearon commented Sep 15, 2016

+40 in min is fine.

@koba04 koba04 mentioned this pull request Sep 15, 2016
@vjeux
Copy link
Contributor

vjeux commented Sep 15, 2016

Shipit :)

@aweary aweary merged commit c78464f into facebook:master Sep 15, 2016
@@ -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, {

Copy link
Collaborator

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?

Copy link
Contributor Author

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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand but ART lives in its own repo. It's only here for running tests. (Yea I know it's confusing.) This means that if we had to change ART in a PR here, real ART will break with next version of React that contains this change. cc @spicyj @zpao

Copy link
Collaborator

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.

Copy link
Contributor Author

@aweary aweary Sep 16, 2016

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

Copy link
Collaborator

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.

Copy link
Contributor Author

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.

Copy link
Collaborator

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?

Copy link
Contributor Author

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.

Copy link
Collaborator

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. :)

@zpao
Copy link
Member

zpao commented Oct 4, 2016

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.

@sophiebits
Copy link
Collaborator

As long as you pick #7757 too we're good.

@zpao
Copy link
Member

zpao commented Oct 4, 2016

That brings us back to the state post- #7598, which was semver-major. Presumably we need to get back to ReactMultiChild.Mixin for ART, which makes me question if we should try to take this at all or if I should look at backporting to fix flow.

zpao pushed a commit that referenced this pull request Oct 4, 2016
This is a manual cherry-pick of 2 PRs, updated to handle differences in the stable branch:
- c78464f - Resolve flow errors with ReactTestRenderer (#7736)
- 7dfa01f - Revert ReactMultiChild to plain object (#7757)
@zpao zpao modified the milestones: 15-next, 15.4.0 Oct 4, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants