React.useMemo 在 class 组件中

React.useMemo in class component

在 class 组件的情况下,有没有办法使用这个钩子或 React API 的一些类似物?

我想知道,在 class 组件的情况下,我是否应该使用一些第三方备忘录助手(例如 lodash memo memoizeOne, 等)或者 class 组件存在一些官方反应 API 方式。

感谢您的帮助。

P.S.

我想生成uuid以防Children发生变化

有了 SFC 组件,我可以像这样使用 useMemo

const keyValue = useMemo(() => uuid()(), [children])

但是如何在没有任何第三方的情况下为基于 class 的组件实现相同的效果,等等
P.P.S。我没有使用 Redux 等,只是纯 React.js

使用getDerivedStateFromProps. The official React docs mentions this technique here.

As of version 16.3, the recommended way to update state in response to props changes is with the new static getDerivedStateFromProps lifecycle.

class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      values: props.values,
      childrenIds: []
    };
  }

  static getDerivedStateFromProps(props, state) {
    if (props.values !== state.values) {
      return {
        values: props.values,
        childrenIds: generateIds(props.values)
      };
    }
    return null;
  }

  render() {
    return JSON.stringify(this.state.childrenIds);
  }
}

根据React docs

If you want to re-compute some data only when a prop changes, use a memoization helper.

文档使用 memoizeOne as library, so this would be a good choice. You can also change keyValue as part of a side effect with componentDidUpdate:

componentDidMount() {
  this.keyValue = uuid()()
}

componentDidUpdate(prevProps) {
  if (this.props.children !== prevProps.children) {
    this.keyValue = uuid()()
    // alternative: store keyValue as state to trigger re-render
  }
}

getDerivedStateFromProps 可以作为极少数情况下的替代方案,其他选项 are usually preferred.

为什么 useMemo 不是 uuid()

的好选择

You may rely on useMemo as a performance optimization, not as a semantic guarantee. In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. (docs)

记忆值 const keyValue = useMemo(() => uuid()(), [children]) 可能会被重新计算,尽管 children 在 React 未来是相同的。这种情况可能会导致不一致,如果 uuid() returns 一个新的 id,但是 children 没有改变。

对于功能组件,根据您的用例,替代方案是 useRefuseEffect