繁体   English   中英

使用 React 钩子实现 shouldComponentUpdate - 只渲染一次子项,但在道具更改时进行 DOM 更改

[英]Implement shouldComponentUpdate with React hooks - Render child only once, but make DOM changes when props change

我有一些使用 shouldComponentUpdate 的 React.Component 工作,并想将其转换为使用 React Hooks,但我不确定它是否可能。

我有一个渲染非常昂贵的 ChartingLibrary 画布的子组件,所以我只想渲染 Child react 组件一次。

图表画布内容依赖于传递给 Child 的 props,并且必须使用传递给 child 的 props 调用 ChartingLibrary 上的某些 api。

所以当传递给child的props发生变化时,需要调用Charting Library上的apis,但是又不想刷新Child组件。

这是与 React Class 一起使用的,如下所示:


    const Parent = () => {
        <Child/>
    }

    export class Child extends React.Component {
        shouldComponentUpdate (nextProps, nextState) {
            ChartingLibrary.init()
            ChartingLibrary.doStuffWithProps(nextProps.data)
            return false
        }
    }

React.memo 有问题:

我最接近 React.Component 版本的是 React.Memo,但我无法从 isSame 函数内部访问 ChartingLibrary。 反应。 React.Component 版本让我可以从组件内部访问 ChartingLibrary,而 React.memo 只能从组件外部访问。


    const Parent = () => {
        <Child/>
    }

    const Child = (props) => {
        ChartingLibrary.init()
        ChartingLibrary.doStuffWithProps(props) 
    }
    const ChildMemo = React.memo(Child, function isSame (prevProps, props) {
        ChartingLibrary.doStuffWithProps(props)
        return true
    })

有没有更好的办法? 我正在尝试用钩子做的事情可能吗?

我猜你的做法是正确的。 React.memo是您实现React.memo的方式。

function MyComponent(props) {
  /* render using props */
}
function areEqual(prevProps, nextProps) {
  /*
  return true if passing nextProps to render would return
  the same result as passing prevProps to render,
  otherwise return false
  */
}
export default React.memo(MyComponent, areEqual);

正如文档中所说:

与类组件上的 shouldComponentUpdate() 方法不同,areEqual 函数在 props 相等时返回 true,如果 props 不相等则返回 false。 这与 shouldComponentUpdate 相反。

希望这会帮助你。

谢谢@Muhammad Zeeshan,我只需要在道具更改时才为文本字段 (RN) 设置动画:

import React, { useEffect, useRef } from 'react';
import { Animated } from 'react-native';
const AnimatedView = props => {
  const animatedOpacity = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    Animated.sequence(
      [
        Animated.timing(animatedOpacity, {
          toValue: 0,
          duration: 500,
          useNativeDriver: true
        }),
        Animated.timing(animatedOpacity, {
          toValue: 1,
          duration: 0,
          useNativeDriver: true
        })
      ],
      { useNativeDriver: true }
    ).start();
  }, [props.children]);

  return (
    <Animated.Text
      style={{
        opacity: animatedOpacity
      }}
    >
      {props.children}
    </Animated.Text>
  );
};

const comparator = (prevProps, nextProps) => {
  if (prevProps.children !== nextProps.children) {
    return true;
  }
  return false;
};

export default React.memo(AnimatedView, comparator);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM