How to properly pass nested properties with distribution attributes? (Jsx)

# one

Hey. I have a code:

class Component extends React.Component { render() { this.props.nested.prop = this.props.parse.nested.prop; return <div>Component</div>; } componentDidMount() { console.log(this.props.nested.prop); } } Component.defaultProps = { nested: { prop: "default" } }; const obj1 = { nested: { prop: "obj1" } }; const obj2 = { nested: { prop: "obj2" } }; class Application extends React.Component { render() { return ( <div> <Component parse={obj1}/> <Component parse={obj2}/> </div> ); } } React.render(<Application />, document.getElementById('app')); //console output: //"obj2" //"obj2" 

Why am I getting 1 variable reference for 2 separate components instead of 2 nested.prop instances for each component? Why does this.props only retain the last set value for all instances of the component after mounting? Is this normal behavior? I think that the correct behavior has different property values ​​for different instances.

Postscript I checked this code here .

# 2

jimfb received the answer: "You are mutating the default prop that was passed in. The line this.props.nested.prop = this.props.parse.nested.prop; is illegal."

My next question is: How to pass nested properties without a manual mutation of props?

For instance:

 Component.defaultProps = { nested: { prop1: "default", prop2: "default" } }; const props = { nested: { prop1: "value" } }; let component = <Component {...props}/>; 

Guide to the code above: the JSX distribution attribute function simply overrides props.nested, and I lose the default nested properties. But that is not what I need. How about implementing a recursive traversal of nested objects in the JSX propagation attribute analysis phase?
Or is there some useful template for this case?

+12
source share
1 answer

This is a really good question!

The short answer is: you cannot do a deep merge with the spread operator - it only does a shallow merge. But you can certainly write a function that will perform objects that intersect and implement deep merging.

This actually leaves you with 3 options:

1) Just do not make a deep merger. If you have a 2-level nested object, you can do such a simple thing:

 const newNested = {...oldProps.nested, ...newProps.nested }; const finalProps = { ...oldProps, nested: newNested }; 

Incorrect merging is a force for you to say explicitly that you will have a new value for the nested property . This is good because it makes your code obvious. You can also try running the above examples here .

2) You can use the library for immutable structures. FE immutable.js . With it, your code will look pretty similar.

 const oldProps = Immutable.fromJS({ nested: { prop1: "OldValue1", prop2: "OldValue2", } }); const newProps = Immutable.fromJS({ nested: { prop1: "NewValue1", } }); const finalProps = oldProps.updateIn(['nested'], (oldNested)=> oldNested.merge(newProps.get('nested')) ) 

3) You can use deep merging: find some implementation in npm or write it yourself and you will have such code (as an example, immutable.js example):

 const finalProps = oldProps.mergeDeep(newProps); 

In some cases, this may be required, but such code makes the update operation implicit , and it raises many problems, which are listed significantly here.

+20
source

All Articles