reactjs 如何防止图像在react可重用组件中的重渲染?

rlcwz9us  于 2023-04-29  发布在  React
关注(0)|答案(1)|浏览(131)

我目前的斗争是,我有一个组件与图像显示在主屏幕上。然而,在提取时,当组件再次用于另一组件时,图像需要一瞬间加载,导致 Flink 。问题是,我想阻止这种渲染,因为最初的渲染发生在主页上。这是我的代码。

import React, { useEffect, useLayoutEffect, useState, useRef, useMemo, memo } from 'react';

// Mui
import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';
import { Container, Box, Paper, Switch, Slide, FormControlLabel, Zoom, Grow } from '@material-ui/core/';
// Rdux
import { useAppSelector } from '../../redux-store/hooks';

interface Props {
  homePage: boolean;
  loading: boolean;
}

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    image: {
      maxWidth: '100vw',
      marginTop: 'auto', // L2 This is to make the image stick to footer..
      backgroundRepeat: 'no-repeat',
      maxHeight: '82vh',
      backgroundSize: 'auto',
      filter: 'grayscale(50%) drop-shadow(12px 12px 12px rgba(128,128,128 ,0.1))',
    },
  })
);

const SplashImages: React.FC<Props> = memo(({ homePage, loading }) => {
  const maleImageUrl = // some url
  const femaleImageUrl =  // some url
  const dogImageUrl =  // some url

  const male = useMemo(() => maleImageUrl, []);
  const female = useMemo(() => femaleImageUrl, []);
  const dog = useMemo(() => trainerImageUrl, []);

  const classes = useStyles();
  // Redux
  const currentUser = useAppSelector((state) => state.auth.currentUser);
  // Local State
  const [isMale, setIsMale] = useState(true);

  useEffect(() => {
    const timeoutId = setTimeout(() => {
      setIsMale(!isMale);
    }, 3000);

    return () => clearTimeout(timeoutId);
  }, [isMale]);

  const showMale = currentUser?.userType !== 'dog' && isMale;
  const showFemale = currentUser?.userType !== 'dog' && !isMale;

  return (
    <>
      <img src={male} className={classes.image} style={{ display: showMale ? 'block' : 'none' }} />
      <img src={female} className={classes.image} style={{ display: showFemale ? 'block' : 'none' }} />
      <img src={dog} className={classes.image} style={{ display: currentUser?.userType === 'trainer' ? 'block' : 'none' }} />
    </>
  );
});

// Export usning memo to prevent re-rendering
export default React.memo(SplashImages);
unguejic

unguejic1#

我认为这个问题是由以下两件事之一引起的:
1.确保您没有在Devtools网络选项卡中打开Disable cache
1.您可以考虑预先预加载图像(display: none不会在后台加载图像,因此解决方案是将图像大小设为1px x x 1px,不透明度为0),以防止图像 Flink :

import React, {
  useEffect,
  useLayoutEffect,
  useState,
  useRef,
  useMemo,
  memo
} from 'react';

// Mui
import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';
import {
  Container,
  Box,
  Paper,
  Switch,
  Slide,
  FormControlLabel,
  Zoom,
  Grow
} from '@material-ui/core/';
// Rdux
import { useAppSelector } from '../../redux-store/hooks';

interface Props {
  homePage: boolean;
  loading: boolean;
}

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    image: {
      maxWidth: '100vw',
      marginTop: 'auto', // L2 This is to make the image stick to footer..
      backgroundRepeat: 'no-repeat',
      maxHeight: '82vh',
      backgroundSize: 'auto',
      filter:
        'grayscale(50%) drop-shadow(12px 12px 12px rgba(128,128,128 ,0.1))',
      display: 'block'
    },
    hide: {
      position: 'absolute',
      width: '1px',
      height: '1px',
      opacity: '0'
    }
  })
);

const cx = (...classes: any[]) => {
  return classes.filter(Boolean).join(' ');
};

const SplashImages: React.FC<Props> = memo(({ homePage, loading }) => {
  const maleImageUrl = '// some url';
  const femaleImageUrl = '// some url';
  const dogImageUrl = '// some url';

  const male = useMemo(() => maleImageUrl, []);
  const female = useMemo(() => femaleImageUrl, []);
  const dog = useMemo(() => dogImageUrl, []);

  const classes = useStyles();
  // Redux
  const currentUser = useAppSelector((state) => state.auth.currentUser);
  // Local State
  const [isMale, setIsMale] = useState(true);

  useEffect(() => {
    const timeoutId = setTimeout(() => {
      setIsMale(!isMale);
    }, 3000);

    return () => clearTimeout(timeoutId);
  }, [isMale]);

  const showMale = currentUser?.userType !== 'dog' && isMale;
  const showFemale = currentUser?.userType !== 'dog' && !isMale;

  return (
    <>
      <img
        src={male}
        className={cx(classes.image, showMale ? null : classes.hide)}
      />
      <img
        src={female}
        className={cx(classes.image, showFemale ? null : classes.hide)}
      />
      <img
        src={dog}
        className={cx(
          classes.image,
          currentUser?.userType === 'dog' ? null : classes.hide
        )}
      />
    </>
  );
});

// Export usning memo to prevent re-rendering
export default React.memo(SplashImages);

相关问题