Update to allow components to render undefined #75
                  
                    
                      rickhanlonii
                    
                  
                
                  announced in
                Announcement
              
            Replies: 0 comments
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment
  
        
    
Uh oh!
There was an error while loading. Please reload this page.
-
Overview
We’ve made update to allow rendering undefined instead throwing.
In this post I want to share a bit about the reasoning and why we’re changing this in React 18.
Background
Before this change, if a component rendered
undefined, React would throw an error at runtime:The intent of this behavior was to help users catch a common issue of forgetting a return statement accidentally. This is an easy mistake when using early returns or multiple returns:
For use cases where this behavior was intentional, you could indicate that by returning
nullinstead:Issues with throwing
There are a couple of issues with throwing at runtime when rendering undefined.
1. Linting is better for this use case
At runtime, you can’t tell the difference between forgetting to return and explicitly returning
undefined, but this is something linting can check for because it operates on the code syntax as it’s written instead of how it’s executed.Linting is also able to give more specific messages for why you may have made an accident, such as “this function is missing a return statement” (consistent-return), or “this expression was unused” (no-unused-expressions). More specific messages with code frames pointing you to the source of the issue will help you find the issue quicker than a generic run time error.
2. Creating a correct type is hard
Another issue of not allowing undefined is that it’s difficult create a proper type for something React can render. For example, in the old behavior where we throw for
undefined, let’s say you want to render thechildrenprop in component:How would you type
ComponentTypeso that it can be used to typechildrenandFoo? You can’t includeundefinedbecause it would error at runtime. But if you excludeundefined, then everywhere you pass the children down to Foo, you would need to check if the children areundefined:Not being able to create a general type of something React can render that you can use in place of any prop or component that is passed through your app has been a long standing issue in the ecosystem. By allowing
undefinedto be rendered, it becomes easy to create a type that’s the same across type systems.Why now?
When we first added this error in 2017, type systems and linting in the ecosystem were not as popular or robust as they are today, and there were a lot of runtime checks like
prop-typesbeing done to help developers find unsafe issues. Since then, the community has evolved and these tools have grown in popularity, so it’s a good time to re-visit this feature to replace it with something better.To give some insight into how the team started considering this change, it recently came up in discussions for future features such as Suspense and server components. For Suspense, we recently made an update to how we handle
nullorundefinedfallbacks, allowing undefined fallbacks to render. But if the fallback is undefined, why doesn't it error? There's an inconsistency there that we wanted to fix.For server components, it’s important to have a general type for things React can render because you may need to be able to accept children passed from server components. The current complexity of types will only become more complex as we add features, so it's important to fix this issue now.
Beta Was this translation helpful? Give feedback.
All reactions