4m1r 4m1r - 1 month ago 16
React JSX Question

React.Component.defaultProps objects are overridden, not merged?

I'm trying to set a defaultProp with an object literal, but after some time I realized that the React class constructor is not merging the default props with the applied props, so I end up with undefined values for any properties in the defaultProps literal that haven't been included in the applied props. Is there a way to merge default props and applied props, or do I need to break up my object into several props?

class Test extends React.Component {
constructor(props) {
super(props);

//props.test is only {one: false}
//props.test.two is undefined

}
render() {
return (<div>render</div>)
}
}

Test.defaultProps = {
test: {
one: true,
two: true
}
}


ReactDOM.render(<Test test={{'one': false}}/>, document.getElementById('#test'));


http://codepen.io/adjavaherian/pen/oYNPLz

Answer

React only does a shallow merge of the default props and the actual props, i.e. nested default props are overridden instead of merged. This is by design.

See this React issue for more background and reasoning why this is the case and potential workarounds:

aside from the potential perf issues here. one issue with this is how do you handle nested complex structures like arrays? concatenation? Union? what about an array of objects? deep object merging can lead to unexpected behaviour, which is why often implementations allow you to specify a merge strategy such as _. merge. I'm not sure how you would do that in prop type declaration.