我正在使用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 (...)
}
我已将photos prop传递到useEffect钩子的依赖项数组中,因此当photo prop更改时,它将触发。我可以看到道具确实在控制台中发生了变化,但是当道具发生变化时,我的useEffect钩子不会触发。这就是我的控制台中显示的内容:
为什么useEffect不触发两次?据我了解,它应该在组件首次渲染时触发,并在photos
道具每次更改时再次触发。
答案 0 :(得分:5)
请尝试确保您的photos
道具是不可变的,
意思是,每次发生更改时您都发送一个新数组,而不会更改该数组
答案 1 :(得分: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
答案 2 :(得分:0)
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>
</>
);
}