我有一个 React 组件,它似乎没有正确重置其初始状态。我使用 Object.assign() 来确保传递下来的 props 具有所有字段(以适应键可能未定义的遗留数据库条目)。
newProfile 是完整的个人资料(带有标题字段),legacyProfile 是添加标题字段之前的条目。为什么/如何传递legacyProfile的组件以某种方式保留来自另一个实例的一些数据(传递newProfile的组件),以及如何防止这种情况以确保我始终以新的profileInitialState开始?
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>
最佳答案
Object.assign
会将第二个及以上所有参数中自己的可枚举属性分配给第一个参数中的对象。所以
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 }
关于javascript - 使用 Object.assign() 时,React 组件不会重置状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60218115/