I read recently that default props for functional components will one day be deprecated in React. It’s currently possible (as of September 2019) to set the default props for functional components like this:
/* --- greet.tsx --- */
import React from "react";
interface Props {
name: string
greeting: string
}
export function Greet({ name, greeting }: Props) {
return (
<h1>{greeting} {name}!</h1>
);
}
const defaultProps: Pick<Props, "greeting"> = {
greeting: "Hello"
}
Greet.defaultProps = defaultProps;
I quite like this approach, but I can understand why it would be deprecated. Adding a custom property onto a function ‘object’ does feel a little strange. Fortunately, we can use TypeScript’s / JavaScript’s default values and object deconstruction as an alternative.
In the code above, we have already deconstructed the props argument to easily access the name
and greeting
props (i.e. { name, greeting }: Props
). We can use that deconstruction to also set a default value for greeting
without using defaultProps
:
/* --- greet.tsx --- */
import React from "react";
interface Props {
name: string
greeting: string
}
export function Greet({ name, greeting = "Hello" }: Props) {
return (
<h1>{greeting} {name}!</h1>
);
}
Just like with the defaultProps
, greeting
now has a default value of "Hello"
. This code for the component appears to be ok, but you’ll notice that TypeScript will not recognise the default value like it does for a default prop. If you don’t set the greeting
prop when using the Greet
component you will get an error similar to this:
To make TypeScript happy we need to mark the greeting property in the Prop
interface as an optional property by appending a question mark to the end of the name:
/* --- greet.tsx --- */
import React from "react";
interface Props {
name: string
greeting?: string
// `greeting` is now marked as an optional property
}
export function Greet({ name, greeting = "Hello" }: Props) {
return (
<h1>{greeting} {name}!</h1>
);
}
Now everything should be working 🎉
I’ve started using this technique in real applications to future-proof components and I’m actually starting to prefer it over the defaultProps
approach. The Props
interface now clearly communicates to other developers which props are required to be set and which ones are optional. It also requires fewer lines of code to implement than defaultProps
. As an added bonus I’ve found that developers who a fairly new to TypeScript can get confused by the Pick
type, so removing the need to use it makes the component more accessible for the entire team.