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
Document best practice for using self-referencing PropTypes #316
Comments
I agree that circular propTypes are needed for a tree-like structure that allows circularity, but that specific need is indeed exceedingly rare. You'd handle this by using a custom propType to wrap the recursion, rather than actually using recursion. |
To clarify, what I'm pointing out by filing this issue is that no clear guidance exists to address this pattern. I've clearly gotten it wrong here, but that's largely because I've been feeling around in the dark absent such guidance.
☝️ Thanks, but I don't understand what that means or whether it differs from your prior recommendation on #246. Can you point to a clear example? Right now, I've constructed the following work-around: type LeafComponentT = InferProps<typeof LeafComponent.propTypes>
function LeafComponent({ id, name }: LeafComponentT) {
return (
<span>{name} ({id})</span>
)
}
LeafComponent.propTypes = {
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
}
interface RootComponentT {
children: NodeComponentT[],
}
function RootComponent({ children }: RootComponentT) {
if (children
&& children.length > 0) {
return (
<ul>
{children.map((child, _) => (
<NodeComponent {...child} />
))}
</ul>
)
} else {
return null
}
}
RootComponent.propTypes = {
children: PropTypes.array.isRequired,
}
type NodeComponentT = RootComponentT & {
leaf: InferProps<typeof LeafComponent.propTypes>,
}
function NodeComponent({ leaf, children }: NodeComponentT) {
return (
<li>
<LeafComponent key={leaf.id} {...leaf} />
<RootComponent children={children} />
</li>
)
}
NodeComponent.propTypes = {
leaf: PropTypes.shape(LeafComponent.propTypes).isRequired,
children: PropTypes.array.isRequired,
} I call this a work-around because there is no runtime type checking of the elements of |
This comment claims this use case is pretty rare, but I'm either ignorant of the alternatives, or I'm not convinced. Anywhere one wants to have a tree-like component structure, one potentially butts up against this limitation. Consider a structure involving
Node
s andLeaf
s as follows:So far, a
Node
is merely a list ofLeaf
s. Now let's say we want to augment ourNode
to contain zero or more entries, each of which may either be aNode
orLeaf
. How is this done? This won't work:You'll get a circular reference type error. So how should one handle this case in the real world? I can find near zero documentation on how to do this, either here or via the React docs. Any guidance would be appreciated.
The text was updated successfully, but these errors were encountered: