Object.assign
назначит собственные перечислимые свойства из всех аргументов 2 и выше в объект в 1 аргументе. Так
editingProfile: Object.assign(profileInitialState, this.props.profile)
видоизменяется profileInitialState
.
Эта строка похожа на
for (const [key, val] of Object.entries(this.props.profile)) {
profileInitialState[key] = val;
}
В результате второй раз этой строки выполняется, результаты первого могут все еще существовать в profileInitialState
.
Вместо этого используйте
editingProfile: Object.assign({}, profileInitialState, this.props.profile)
, чтобы создать совершенно новый объект:
const profileInitialState = {
name: '',
title: '',
headline: '',
bio: ''
}
class Bio extends React.Component {
constructor(props) {
super(props);
this.state = {
editingProfile: Object.assign({}, profileInitialState, this.props.profile)
}
}
render() {
const { profile } = this.props;
const { editingProfile } = this.state;
console.log(profile); // props profile has correct info
console.log(editingProfile); // state profile takes on old values
return (
<div>
<h1>{editingProfile.name}</h1>
<h2>{editingProfile.title}</h2>
<h3>{editingProfile.headline}</h3>
<p>{editingProfile.bio}</p>
</div>
);
}
}
const newProfile = {
name: 'Test 1',
title: 'Title 1',
headline: 'Headline 1',
bio: 'Bio 1'
}
const legacyProfile = {
name: 'Test 2',
title: 'Title 2',
bio: 'Bio 2'
}
ReactDOM.render(
<React.Fragment>
<Bio profile={newProfile} />
<Bio profile={legacyProfile} />
</React.Fragment>,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root">
<!-- This element's contents will be replaced with your component. -->
</div>
Или, еще более кратко:
editingProfile: { ...profileInitialState, ...this.props.profile }