javascript - 使用 Object.assign() 时,React 组件不会重置状态?

标签 javascript reactjs object

我有一个 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/

相关文章:

java - 如何在 Java 中将 JavaScript 日期转换为日期?

javascript - 如何将 css 应用于 textarea 标签内以逗号分隔的文本? (React.js 元素)

javascript - React Router 4、LINK 和 ROUTE 在不同的布局上

java - Java 中类引用的行为

javascript - 如何有效地对对象进行分组并为每组对象进行计算

java - 在 Java 中动态创建对象

javascript - 应将用户重定向到响应页面的状态代码是什么?

Javascript 宏 : implementing F# style forward pipe operator

javascript - Displayformat 格式化失败

reactjs - 如何让 react 将自定义钩子(Hook)的返回值视为稳定的身份?