簡體   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