React Spread Props

Just like how you can spread with objects you can also spread props in JSX.

Let's say we have a Stars component which takes two props: stars= and color=:

<Stars stars={5} color="yellow" />

We can spread these two props from an object into <Stars> like this:

const starsProps = {stars: 5, color: 'yellow'}
<Stars {...starsProps} />
// same as <Stars stars={5} color="yellow" />

Just like regular object spreading this it's last one wins. For example:

const starsProps = {stars: 5, color: 'yellow'}
<Stars {...starsProps} color="blue"/>
// same as <Stars stars={5} color="blue" />
const starsProps = {stars: 5, color: 'yellow'}
<Stars color="blue" {...starsProps} />
// same as <Stars stars={5} color="yellow" />

children prop

React has a special prop called children. children is the stuff that goes between the opening and closing JSX tags.

Example:

<p>Children!</p>
<div>
  <input /> // children
</div>

You can also write these two examples as:

<p children="Children!" />
<div children={<input />} />

When you write a custom component you can pass children in the same way, for example:

<Stars stars={5} color="yellow">
  <p>*</p>
</Stars>

You can access children by saying: props.children inside your component.

Building reusable components using spread

Spreading is particularly useful if you'd like to 'wrap' or 'extend' another component.

Let's say we want to write a <Text> component for our app, rather than using <p> everywhere.

We can do this like this:

const Text = props => <p {...props} />

Because we spread props this allows us to pass any props <p> accepts into Text>, for example:

<Text style={{color: 'red'}}>Hello</Text>

This sets style as expected and sets the children to Hello.

Let's say we want to make our text blue and font size 11px over our entire website:

const Text = props => <p style={{color: 'blue', fontSize: '11px'}} {...props} />

Now everywhere we've used <Text> is now blue and font size 11px, rather than having to make code changes in many places.

What if we want to make the text red in just one place:

<Text style={{color: 'red'}}>Red Text</Text>
// => <p style={{color: 'red'}}>Red Text</p>

This works because we {...props} in our Text component. However we lose fontSize: '11px' because 'last prop wins'.

We can fix that by spreading any styles together:

const Text = props => <p {...props} style={{color: 'blue', fontSize: '11px', ...props.style}}  />

We moved {...props} so that our style code is last, and wins. We then use {color: 'blue', fontSize: '11px', ...props.style} to spread any additional styles into {color: 'blue', fontSize: '11px'}.

Our previous example now works as expected:

<Text style={{color: 'red'}}>Red Text</Text>
// => <p style={{fontSize: '11px', color: 'red'}}>Red Text</p>

This technique is extremely powerful and used regularly when writing React code.