3

In React, normally, we pass props to child component by following way:

const Parent = ({ foo, bar, baz, myFoo, myBar, myBaz }) => <Child foo={foo} bar={bar} baz={baz} /> (1)

Currently I figured out an alternative way to do this:

const Parent = ({ foo, bar, baz, myFoo, myBar, myBaz }) => <Child {...{ foo, bar, baz }} /> (2)

IMO, (2) saves a lot of time and typing effort. However:

  1. Are there any cons with (2)? For example, is (2) considered as React anti-pattern?
  2. I know talking about performance without measuring is bad, but I wonder if there are any hurt performance issues with (2)?

Update 1: I have added myFoo, myBar, myBaz in Parent's props. Please note that I do not want to spread all props to Child component, because it's considered as bad practice that results in unnecessary props in Child component.

Cam Song
  • 492
  • 2
  • 11
  • 1
    Not recomended due to readability https://reactjs.org/docs/jsx-in-depth.html#spread-attributes – Rashomon Apr 02 '20 at 16:29
  • @Rashomon What if my team (about 5-6 persons) all find it easier and more readable to use? Any ideas except readability? – Cam Song Apr 02 '20 at 17:28
  • Does this answer your question? [How to pass props to {this.props.children}](https://stackoverflow.com/questions/32370994/how-to-pass-props-to-this-props-children) – Michael Freidgeim Aug 22 '21 at 02:28
  • @Rashomon, thanks for the link https://reactjs.org/docs/jsx-in-depth.html#spread-attributes, but it does not say that using spread is not recommended. “ We recommend using this syntax sparingly.” – Michael Freidgeim Apr 09 '22 at 03:36

3 Answers3

2

You could rewrite your code to:

const Parent = (props) => <Child {...props} />

and that's actually very common to do in react. If you need foo, bar or baz somewhere else you could write it like this:

const Parent = (props) => {
  const { foo, bar, baz } = props;
  // do something with foo, bar or baz
  return <Child {...props} />;
}

To come back to your questions:

1) No, that's not an anti pattern, but you should use approaches above instead (I never saw code similar to your example in any project so far). A disadvantage could be that you don't really now any more what you pass down to the Child and that you might pass down more than you need. E.g. props of Parent could have an additional field like faz and you would just pass it to the Child and it would never use it.

2) I can't think about any meaningful performance issue here. In my projects I use this approach very often and I never noticed any performance problems.

ysfaran
  • 5,189
  • 3
  • 21
  • 51
  • I have updated my question. Please check Update 1 below for details. As for "that you might pass down more than you need", the reason I decide to switch to approach (2) is to avoid that. Instead of ``, I can see it clearly and control which props are passed down. – Cam Song Apr 02 '20 at 17:32
  • Understood! I personally would prefer (1) approach then, because the second approach looks just odd (as I said I never saw it before). Or I would at least do `const childProps = { foo, bar, baz }` and then `` which is also not great, but IMHO would improve readability at least a bit .. – ysfaran Apr 03 '20 at 13:40
  • The more you get used to something, the lazier you become. Beyond the readability, I think (2) is more suitable for the experienced, cuz it saves lots of typing effort :D. Please consider an upvote if you find it potential and useful! – Cam Song Apr 03 '20 at 14:03
1

The only drawback about it is that sometimes is hard to understand, by using approach one, you're making the code more readable and explicit. Of course if you have some sort of documentation for the components, like storybook or something that will help the other devs to understand the props that the component needs, it does not matter to use the second approach (prop spreading), but to make things readable you should stick with the first one (declaring each prop one by one).

Check this eslint-react-plugin rule https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md it summarizes why is better to use the first approach.

jean182
  • 3,213
  • 2
  • 16
  • 27
  • Appreciate the rule. Don't you think this `{...{ foo, bar, baz }}` will create a brand new object on every single render? Please have a look at this one: [eslint jsx-no-bind rule](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md). I wonder if the approach (2) is kinda the same as the arrow function in a JSX prop that will create a brand new function on every single render -> which may cause unnecessary re-renders – Cam Song Apr 02 '20 at 18:01
  • 1
    I don't think it works that way, because you're passing the props in a different way but is doing the same as for example using the first approach, I don't see it as an issue, but IMHO I prefer the approach one, I know it can take more time to write it but the code readability is way better. – jean182 Apr 02 '20 at 18:22
0
  1. Why would it be consider anti-pattern ? After all this is where spread operator is useful, right ?

  2. You should not care about performance. This will be transpiled to plain old javascript anyway(through babel or something similar). This is just syntactic sugar.

Cristian Riță
  • 561
  • 3
  • 13
  • Don't you think this `{...{ foo, bar, baz }}` will create a brand new object on every single render? Please have a look at this one: [eslint jsx-no-bind rule](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md). I think the approach (2) is kinda the same as the arrow function in a JSX prop that will create a brand new function on every single render -> which may cause unnecessary re-renders – Cam Song Apr 02 '20 at 17:42