【问题标题】:Update component state when props change当 props 改变时更新组件状态
【发布时间】:2019-01-30 13:00:48
【问题描述】:

我有一个轮播组件,它接收轮播项目作为道具。我将当前活动的轮播项目存储在轮播组件的状态中。轮播本身是一个滑块,由 GSAP 可拖动控制。轮播项目的数量可能会改变,然后我想重置状态以使第一个项目处于活动状态。如何使用当前的 React 版本实现这一点?我试过了:

static getDerivedStateFromProps(props, state) {
  if (state.openItem > props.items.length) {
    return {
      openItem: 0,
    };
  }
  return null;
}

但这只会在当前项目大于项目总数时重置。我想要一种可以比较 prevProps 的方法,以便检查项目总数是否已更改。如果我在 componentDidUpdate 中设置状态,可能会导致无限渲染循环。我不想将状态拉出到父组件,因为这会使父组件需要太多功能才能使轮播组件可重用。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    items 存储在状态中,然后像这样使用getDerivedStateFromProps

    static getDerivedStateFromProps(nextProps, prevState) {
      if (nextProps.items.length !== prevState.items.length) {
        return {
          openItem: 0,
          items: nextProps.items
        };
      }
      return null;
    }
    

    这符合要求,但理想情况下,您应该想办法检查items 的内容是否相等,然后触发状态更改。您可以像这样使用 lodash 中的 isEqual 并将相等性检查替换为:

    if (_.isEqual(nextProps.items.length, prevState.items.length))
    

    *请注意,isEqual 会执行深度相等检查,并且可能会对性能产生影响。

    【讨论】:

    • 谢谢,实际上我同时想出了一个类似的解决方案。我将对象的散列从外部传递到组件中,我将其设置在状态内部。然后在 getDerivedStateFromProps 中,我将新哈希与状态中的旧哈希进行比较。如果它们不匹配,我会重置 openItem。
    • 但是从外部发送哈希不会给轮播的消费者增加额外的责任吗?
    • 是的,你说得对,最好在组件内部计算。
    • 我这样做是因为我将实际组件作为道具传递,所以我不确定当数据相同时,散列这些组件是否仍会产生相同的散列。
    【解决方案2】:

    您可以使用 getSnapshotBeforeUpdate() 方法来比较 prevProps,以便检查项目总数是否发生了变化。

    getSnapshotBeforeUpdate(prevProps, prevState) {
        // you can compare the previous prop value and previous state value as per you requirement
        if (prevProps.openItem.length > prevState.openItem.length) {
          // your code
        }
        return null;
      }
    

    【讨论】:

    猜你喜欢
    • 2021-06-08
    • 2021-08-11
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-25
    • 2020-09-30
    相关资源
    最近更新 更多