React.Component.defaultProps objects are overridden, not merged?
This is kind of late to answer but I couldn't find any official or better ways to assign default props
that way so that the props would be merged with the defaults!
I did it in my own way as shown below:
- Define a
defaultProps
variable before the rendering function or class - Use
const var = Object.assign({}, defaultProps.var , props.var);
to get the props object var merged with the default variable var.
Of course, you should do a little more coding for nested objects and arrays to make this approach go well! the assign
function is for shallow merging.
The best approach is using _.merge
function of *loadash library.
- Assign
App.propTypes
andApp.defaultProps
The complete example
import React from 'react';
import PropTypes from 'prop-types';
const defaultProps = {
user: {
id: 0,
name: 'Mike',
family: 'wheeler',
},
address: {
addr1: 'Saint Louis, Arsenal Street',
addr2: '',
tel: null,
},
color: 'orange',
weight: 60,
age: 20,
};
.
.
.
export default function App(props){
const {color, weight, age} = props;
const user = Object.assign({}, defaultProps.user , props.user);
const address = Object.assign({}, defaultProps.address, props.address);
return (<div></div>);
}
App.propTypes = {
type: PropTypes.string.isRequired,
user: PropTypes.shape({
id: PropTypes.number,
name: PropTypes.string,
family: PropTypes.string,
}),
address: PropTypes.shape({
addr1: PropTypes.string,
addr2: PropTypes.string,
tel: PropTypes.string,
}),
color: PropTypes.string,
weight: PropTypes.number,
age: PropTypes.number,
};
App.defaultProps = defaultProps;
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.