-
Notifications
You must be signed in to change notification settings - Fork 1.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
property children
not found in props of React element ...
#1964
Comments
Dupe of #1934 |
For now I have had to resort to the following: type Props = {
children?: ReactElement,
other: number,
};
function Foo({ children, other } : Props) {
return (
<div>...</div>
);
} |
fast offtopic : |
@ctrlplusb you can workaround without using a maybe prop: <NavigationBar children={<span>flow bug (this will get overridden by the children below)</span>}>
<View style={ styles.left }>
...
</NavigationBar> |
@szagi3891 It's here: https://github.com/facebook/flow/blob/master/lib/react.js#L32 I thought it has to be |
Is there any update on this issue? I just just ran into this. |
My real poor workaround is to always do |
@MoOx Hey, why do you write the dollar sign between |
@wildeyes |
Cut out extra flowignore lines that are no longer necessary now that react-motion uses flow. Use `children` prop to work around facebook/flow#1964
My workaroud:
Usage:
|
Hitting this issue... bread and butter React syntax. Work arounds feel a bit stinky :( |
This syntax works for me and I believe was the recommended change when upgrading from 0.25.0 // @flow
import React, {Element} from 'react' // EDIT this should be importing type!!
type Props = {
children: Element<any>
} And the signature for render is render (): Element<any> Am I missing something in the question/problem? I made this change quite some time ago and it is working well. This doesn't seem like a workaround. EDIT: I've left the above for posterity, but after more use it seems that we should be using |
@rosskevin Well I'm fairly new to Flow at the moment, so maybe I'm not understanding correctly! Here's my example:
So in this, I'm saying by
... I get a Flow error of The only "fix" I can see right now is changing EDIT: Same issue with using |
@Ehesp - I suggest two things
Here's how I would refactor your component: // @flow
import React from 'react'
import pure from 'recompose/pure'
import { TouchableHighlight, Text } from 'react-native'
type Props = {
onPress: Function,
children: Element<any>
}
export default pure((props: Props): Element<any> => {
const { onPress, children, ...rest } = props
return (
<TouchableHighlight onPress={onPress}>
<Text>
{children}
</Text>
</TouchableHighlight>
)
}) This is untested but I think it should work for you. |
JSX converts to something like this:
Flow recognizes that the 2nd parameter is where props come from, but it doesn't seem to recognize that the 3rd parameter gets mixed into props under the key This workaround works because you're moving children from the 3rd parameter into the 2nd parameter <Div
children={(
<span>Works nicely</span>
)}
/> becomes React.createElement(Div, {
children: React.createElement(
"span",
null,
"Works nicely"
)
}); If you use |
@rosskevin I corrected your untested code here. You can see that at the bottom I am passing children to I dumped the |
@AsaAyers - I corrected your correction ;) with imports here I haven't seen this problem but it does seem that you have to make Here is a reduced test case that seems to prove either this is a bug (or my misunderstanding). |
That doesn't work for elements that actually require children. react-motion specifically requires a function to be passed as the children prop. |
So apparently the fix: a7878eb was reverted in 0185892, which means that flow currently can't check whether the children prop has been set in jsx. From the revert:
Still, eventually supporting jsx children would be nice, it's a pretty crucial part of using react. Any feedback on whether there will be support for this in the future? |
Every few months I come back and try Flow to see if it's ready. When trying to add Flow to my codebase it never takes me long to find the show stoppers. It seems I can only use flow if I significantly change the style of my code to avoid JS features where Flow is buggy. I guess I'd need to drop JSX to avoid this. If this were the only problem I might consider one of the workarounds here. But for now I'm back to subscribing to issues and I'll try again in a few months when some of them close. |
@AsaAyers I recently flowtyped my relatively huge project. You can check it. https://github.com/este/este |
@AsaAyers If you are not sure what to use, use any. Even /* @flow weak */ is immensely useful. Or check how I flowtyped Fela robinweser/fela#134 |
A bug in flow (facebook/flow#1964) prevents it checking in it's children prop has been set in jsx. You can make flow ignorant to this prop by setting it as optional. Addresses chenglou#375
I do agree - and it is painful. Especially considering they come from the same parent. However, I do feel that it is a rabbit hole. Unless they can define the relationship between an argument and a property on another argument abstractly, or we are provided a mechanism to define required In saying this, I am no Facebook engineer, I'm a pleb with a laptop - so I'm sure they will figure out something that avoids tightly coupling flow to react while resolving this issue. |
Off the top of my head, here's some places where different uses of JSX differ:
You could theoretically make configuration for each of these in .flowconfig:
But in practice, most people just want
|
Could it be typed something like this? /* @flow */
type Props = {
foo: string,
children: number
}
type RC<P> = (props: P) => void
declare var Foo: RC<Props>
declare function createElement<C, P: { children: C }>(component: RC<P>, props: $Diff<P, {children: C}> & {children?: void}, children: C): void
declare function createElement<P>(component: RC<P>, props: P, children: void): void
createElement(Foo, {foo: 'hi', children: 3})
createElement(Foo, {foo: 'hi'}, 3) |
@aaronjensen seems like a good start. But Flow still doesn't “understand” that JSX children would be the third argument of Besides that, these declarations don't handle multi-element children the way <Foo>
<i />
<i />
<i />
</Foo>
// equals to:
createElement(Foo, null, createElement('i'), createElement('i'), createElement('i'));
// and not:
createElement(Foo, null, [createElement('i'), createElement('i'), createElement('i')]); |
Really? What does it do with JSX then? I was assuming that it translated it into a React.createElement call (if you use the default pragma). How else would it type proptypes or the children prop? Babel certainly "understands" it. As for the multiple children, I think you can handle that too: /* @flow */
type Props = {
foo: string,
children: number
}
type BarProps = {
foo: string,
children: Array<number>
}
type RC<P> = (props: P) => void
declare var Foo: RC<Props>
declare var Bar: RC<Props>
declare function createElement<C, P: { children: C }>(component: RC<P>, props: $Diff<P, {children: C}> & {children?: void}, children: C): void
declare function createElement<C, P: { children: C }>(component: RC<P>, props: $Diff<P, {children: C}> & {children?: void}, ...children: C): void
declare function createElement<P>(component: RC<P>, props: P, children: void): void
createElement(Foo, {foo: 'hi', children: 3})
createElement(Foo, {foo: 'hi'}, 3)
createElement(Bar, {foo: 'hi'}, 3, 3, 3) |
@aaronjensen Yeah! And I guess this is the main bug here: Flow can only handle normal JSX props ( You can see the issue using your example adding the same elements in JSX syntax. |
Considering how Facebook & Co. uses React and (I would assume) also use Flow, I wonder how they handle this problem themselves... 🤔 |
Right, which is what we're discussing in this thread. They cannot handle it now, but I'm wondering if one way for them to handle it is with a better signature of React.createElement. The example you linked doesn't really prove anything because it's still using the built-in React.createElement jsx pragma. Unfortunately, Try loading that up and changing the children types. The only thing the signature doesn't handle right now afaik is JSXIntrinsics because I'm not entirely sure how to type those (and maybe they aren't either) |
Typescript just merged support for this: microsoft/TypeScript#15160 |
React flow typing excludes defaultProps from the config of props that need to be provided to Config: $Diff<$Diff<Props, DefaultProps>, {children: any}> |
@Hypnosphi Sometimes you want to enforce the type of children; having the type be ignored wouldn't help there. |
@agentme yes, but normally children are provided separately from props. UPD. The Config: $Diff<$Diff<Props, DefaultProps>, {children: $PropertyType<Props, 'children'>}> |
…ing AnimatedBar
Just tried @rosskevin 's example again with Flow Is this intentional or actually a bug currently in Flow? Strangely enough, it doesn't appear to be actually checking the type of the children: |
@karlhorky I may be mistaken, but wouldn't you have to do this? import React, { type Element } from 'react' Otherwise, you could use the global |
Hm, this doesn't make a difference for the result. |
Infer |
Ooo, does that mean this is fixed? |
I hope so, even though nobody on the dev team said anything about it. My cynical side expects this to break again in the next releases. |
Almost, it checks for the presence of children but it doesn't do type checking yet. |
Flow v0.53 supports children out of the box!!
More info: https://flow.org/en/docs/react/children/ |
Now that Flow v0.53 has improved the Component type and made |
Flow doesn't understand jsx + children (facebook/flow#1964) so this makes the prop optional and adds an invariant to make sure it was actually passed. Closes expo#301 fbshipit-source-id: 76ea6d7
This issue showed when I upgraded from 0.25 to 0.27...
I think I am still having issue.
Here is a component
And here is a place where it is throwing errors
Looks like a bug. Or maybe I am doing something wrong?
The text was updated successfully, but these errors were encountered: