1

In my react application I am passing parent's state to child as a prop like so:

<Child parentsState={...this.state} />

and it works. but then i thought why not should i pass this.state without spread syntax and i did like:

<Child parentsState={this.state}  

and it worked too. mostly i am using spread syntax with arrays and i do not know is there a difference between object without spread syntax and without it?

Thank You!

iLiA
  • 3,053
  • 4
  • 23
  • 45

3 Answers3

7

First of all it's worth nothing that passing entire state to component as prop(s) is an antipattern. It results in Child being dependant on parent's state structure, and every time you change parent you will also need to change Child. Also it's not clear from inside Child which props you receive and you will always have to go to parent source code to find out

Regarding your question: both cases are the same, except in first example you create a new object from this.state that looks exactly like the state, but it is still a brand new object, while in second case you pass the state object itself

Also note the error, <Child parentsState={...this.state} /> will not compile, but <Child parentsState={{...this.state}} /> will

Max
  • 4,473
  • 1
  • 16
  • 18
  • My Child component is a form and data from that form is affecting another components inside Parent component so i need child to be dependant on parents state structure – iLiA Oct 26 '19 at 16:34
  • There is a high chance that you don't need **entire** parent's state in your Child. Pass only props that are necessary, alternatively, declare parent state like `this.state = { form: { ... }, unrelatedKey: '...', anotherUnrelatedKey: '...' }` and pass only `form` to child, e.g. `` – Max Oct 26 '19 at 16:40
  • i could declare variable inside render and exclude properties but why should i do that for just two properties when i can just create a copy of object and pass that – iLiA Oct 26 '19 at 16:44
  • Using nested state is not a bad practice. And in your case it is unavoidable, too. You don't want to mix your form keys with other keys that are not related to the form. Regarding your second question - imagine your Child component gets big, and you want to reuse it it another parent. By just looking at Child component you can't tell which props it expects. There is just one - `parentState`, but what keys is it supposed to have? To find this out you need to read entire Child implementation (at least) – Max Oct 26 '19 at 16:52
  • i did used nested states and because of updating it turned as nightmare for me i did some researches on stackoverflow and everyone suggested not to use nested objects inside state check this: https://stackoverflow.com/questions/43040721/how-to-update-nested-state-properties-in-react by the way in my child component i only get form keys as variables not other keys so in any case i would also like to check child components content because i do not use same keys for properties in state and also this is unique child component and it is not reused and even if it is i could just get the whole – iLiA Oct 26 '19 at 16:59
  • object in child and then get the values i want – iLiA Oct 26 '19 at 16:59
2

Assuming your first one is this (with the {{ and }}):

<Child parentsState={{...this.state}} />

the difference between that and

<Child parentsState={this.state} />

is that in the first one, a shallow copy of this.state is created and that copy is passed to Child, but in the second one this.state is passed to Child directly.

The second means that code in Child could directly modify this.state, which is a Bad Thing™. :-) (The first may mean that too, if this.state contains properties that refer to objects or arrays.)

They're both probably something you want to avoid, at least if this.state has any properties referring to objects (in which case the first one isn't too bad).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
-2

The difference between normal Object and spreading Object can be defined as : -

var obj = {name: 'stackoverflow'}

  1. var obj1 = {...obj}

    Output will be as

    obj1 = {name : 'stackoverflow'}

  2. var obj2 = {obj}

    Output will be as

    obj1 = {obj: {name : 'stackoverflow'}}

  • Also note that the outer `{}` in `parentState={blah}` are JSX expression delimiters, not JavaScript. `` does **not** create an object and give it an `obj` property. – T.J. Crowder Oct 26 '19 at 16:29