【问题标题】:React useEffect hook does not fire when prop dependency changes当 prop 依赖项更改时,React useEffect 钩子不会触发
【发布时间】:2020-06-03 09:41:32
【问题描述】:

我正在使用 useEffect 挂钩根据传入的 photos 道具中的数据进行 API 调用。

const ImageCarousel = ({ src, photos }) => {
  const [photoList, setPhotos] = useState([]);
  const storageRef = firebase.storage().ref();
  console.log("photos prop:", photos);

  const getImage = photoId => {
    return new Promise((resolve, reject) => {
      storageRef
        .child("images/" + photoId)
        .getDownloadURL()
        .then(url => resolve(url))
        .catch(error => reject(error));
    });
  };

  useEffect(() => {
    console.log("trigger");
    Promise.all(
      photos.map(async photoId => {
        const url = await getImage(photoId);
        return url;
      })
    )
      .then(photoUrls => {
        setPhotos(photoUrls);
      })
      .catch(e => console.log(e));
  }, [photos]);

return (...)
}

我已将照片道具传递到我的 useEffect 钩子的依赖数组中,因此当照片道具更改时它应该会触发。我可以看到控制台中的道具确实发生了变化,但是当道具更改通过时,我的 useEffect 钩子不会触发。这是我的控制台中显示的内容:

为什么 useEffect 没有触发两次?据我了解,它应该在组件第一次渲染时触发,并在每次 photos 属性更改时再次触发。

【问题讨论】:

  • 您是否尝试将不同的照片道具值传递给组件并检查是否触发了useEffect? useEffect 只会在新值与旧值不同时触发。
  • 是的,已经尝试使用不同的道具而不是传递一个空数组,但它仍然没有触发useEffect。
  • 根据控制台屏幕截图,我觉得您将相同的值传递给道具,这就是为什么我这样通知的原因,如果您添加了传递道具,那么检查确切的问题会很好

标签: javascript reactjs react-hooks


【解决方案1】:

尝试确保您的 photos 属性是不可变的, 意思是,每次发生变化时都发送一个新数组,而不是改变数组

【讨论】:

  • 也许这作为评论比作为答案更有价值,但感谢您的帮助
  • 多亏了你,我现在有足够的声誉来添加 cmets :)
  • 这确实是问题所在。我正在使用Array.splice() 修改一个数组并将其作为新道具传递。 splice 不是一成不变的,但是当我更改为 Array.filter() 时,它工作得很好。谢谢!
【解决方案2】:

这可能不是最正确的答案,但我已经尝试过了,它确实有效。帽子提示https://dev.to/stephane/how-to-make-sure-useeffect-catches-array-changes-fm3

useEffect(() => {
  console.log("trigger");
  Promise.all(
    photos.map(async photoId => {
      const url = await getImage(photoId);
      return url;
    })
  )
  .then(photoUrls => {
    setPhotos(photoUrls);
  })
  .catch(e => console.log(e));
}, [JSON.stringify(photos])); // stringify the array used as the trigger, and it'll catch the change

【讨论】:

    【解决方案3】:

    useEffect 会在你传递新数据时更新,找到下面的示例代码并检查 console.log。

        import React, { useState, useEffect } from "react";
    
        const EffectCheck = ({value}) => {
            console.log('Component Trigger', value);
            useEffect(() => {
                console.log('Updated Effect', value);
            },[value]);
    
            return (
                <div>{value}</div>
            )
        }
    
        export default function() {
            const [checkValue, setCheckValue] = useState(Math.random());
            const [dynamicCheckValue, setdyamicCheckValue] = useState(Math.random());
    
            return (
                <>
                    <div><h3>No Update</h3>
                        <EffectCheck value={checkValue}/>
                    </div>
                    <div><h3>New Update</h3>
                        <EffectCheck value={dynamicCheckValue}/>
                    </div>
                    <button onClick={() => setCheckValue('Math.random()')}> No Update</button>
                    <button onClick={() => setdyamicCheckValue(Math.random())}> New Update</button>
                </>
            );
        }
    
    
    

    【讨论】:

    • 谢谢,但是这个例子和我上面做的有什么区别?
    • 我只是把这个例子告诉我们需要传递不同的 props 值,如果我们传递相同的 props 值会发生什么
    猜你喜欢
    • 1970-01-01
    • 2020-01-19
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 2021-10-25
    • 1970-01-01
    • 2020-03-02
    相关资源
    最近更新 更多