【问题标题】:React losing variable inside of useEffect?在useEffect中反应丢失变量?
【发布时间】:2021-11-26 01:25:21
【问题描述】:

我正在尝试实现图像幻灯片。 setInterval 在 useEffect 内部使用,以在 x 秒后更改图像。 currentImage 状态保持当前图像,x 秒后它将变为下一个图像,但 react 告诉我每次渲染后索引变量都会丢失。

  const images = [one, two, three, four, five, six, seven];

  const [currentImage, setCurrentImage] = React.useState();

  let index = 0;

  useEffect(() => {
    setInterval(() => {
      if (index < images.length) {
        setCurrentImage(images[index]); 
        index++; 
        console.log(images[index]);
      } else {
        index = 0; // If so, reset the index
      }
    }, 5000);
  }, []);


<Grid
      item
      xs={false}
      sm={4}
      md={7}
      sx={{
        backgroundImage: `url(${currentImage})`,
        backgroundRepeat: "no-repeat",
        backgroundSize: "cover",
        backgroundPosition: "center",
      }}
    ></Grid>

从 React Hook React.useEffect 内部对 'index' 变量的分配将在每次渲染后丢失。要随着时间的推移保留该值,请将其存储在 useRef Hook 中,并将可变值保留在 '.current' 属性中。否则,你可以直接在 React.useEffect 中移动这个变量

【问题讨论】:

    标签: javascript html reactjs react-hooks frontend


    【解决方案1】:

    只要用useState改变索引,记得清空定时器。

    const images = [one, two, three, four, five, six, seven];
        
          const [currentImage, setCurrentImage] = React.useState();
          const [index,setIndex] = useState(0)
          
          useEffect(() => {
           let timer = setInterval(() => {
              if (index < images.length) {
                setCurrentImage(images[index]); 
                setIndex(prev=>prev+1)
                console.log(images[index]);
              } else {
                setIndex(0) // If so, reset the index
              }
            }, 5000);
              return () => {
                clearTimeout(timer)
              }
          }, []);
        
        
        <Grid
              item
              xs={false}
              sm={4}
              md={7}
              sx={{
                backgroundImage: `url(${currentImage})`,
                backgroundRepeat: "no-repeat",
                backgroundSize: "cover",
                backgroundPosition: "center",
              }}
            ></Grid>
    

    你也可以这样做:

    const images = [one, two, three, four, five, six, seven];
        
         
          const [index,setIndex] = useState(0)
          
          useEffect(() => {
           let timer = setInterval(() => {
              if (index < images.length) {
                setIndex(prev=>prev+1)
                console.log(images[index]);
              } else {
                setIndex(0) // If so, reset the index
              }
            }, 5000);
              return () => {
                clearTimeout(timer)
              }
          }, []);
        
        
        <Grid
              item
              xs={false}
              sm={4}
              md={7}
              sx={{
                backgroundImage: `url(${images[index]})`,
                backgroundRepeat: "no-repeat",
                backgroundSize: "cover",
                backgroundPosition: "center",
              }}
            ></Grid>
    

    【讨论】:

    • 它不会更改图像,而且它会在 chrome 控制台中输出相同的图像。但是,当我将图像和索引添加为依赖项时,它会更改当前图像,但反应告诉我“'images' 数组使 useEffect Hook 的依赖项(第 96 行)在每次渲染时都发生变化。将其移动到 useEffect 回调中。或者,将 'images' 的初始化包装在它自己的 useMemo() Hook"
    【解决方案2】:

    使用 setTimeout 并在 useEffect 的依赖数组中添加索引。在那个 setTimeout 中,您将更新您的索引。但是不要将索引存储为变量,将其存储在状态中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-10
      • 2012-08-06
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2019-10-28
      • 2021-09-28
      • 1970-01-01
      相关资源
      最近更新 更多