UI 中的图像在使用 State Hooks 时不会更新
Image in UI doesn't update when using State Hooks
我有一个状态钩子变量定义如下:
const [imageURL, setimageURL] = useState(null);
我正在使用 expo-image-picker 从我的图库中获取图像并将其上传到 firebase 存储。然后我得到这张图片的 URL 并相应地更新 imageURL 的值。
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log(result);
if (!result.cancelled) {
uploadImage(result.uri, 'Profile-picture')
.then(() => {
console.log('it work')
})
.catch(error => {
console.log('it does not work')
console.error(error)
})
}
}
const uploadImage = async (uri, imageName) => {
const user = firebase.auth().currentUser
const currentUser = user.uid
const response = await fetch(uri)
const blob = await response.blob()
const ref = firebase.storage().ref(currentUser + '/profilePicture/' + imageName)
ref.put(blob)
ref.getDownloadURL()
.then((url) => {
setimageURL(url)
setLocalStorage(url)
})
}
当页面首次加载时,该值为空,因此有一个空白图标。上传图片并获得 URL 后,我的应用程序上的 UI 不会更新以显示新图片。除非我上传另一张新图片,否则它将保持空白。一旦发生这种情况,UI 将更新,但它现在将显示我第一次上传的图像。关于我可能做错了什么的任何想法?
注意:我什至尝试添加一个文本组件并传入 imageURL 变量以显示当前 URL,由于某种原因,此文本会正确更新,但图像不会。 (此处未显示)
return (
<View style={styles.container}>
<KeyboardAwareScrollView
style={{ flex: 1, width: '100%' }}
keyboardShouldPersistTaps="always">
<Avatar
size="xlarge"
rounded
source={{
uri: imageURL
}}
icon={{ name: 'user', type: 'font-awesome' }}
activeOpacity={0.7}
containerStyle={{alignSelf: 'center', backgroundColor: '#89CFF0', marginTop: 50}}
>
</Avatar>
发生这种情况是因为您在子组件中使用了图像源。
使用 imageURL 的初始状态 null 构造子组件。
当父组件中的状态更新时,子组件即 <Avatar>
不知道此更新并且不会重新呈现。不建议将初始状态值传递给子组件。但如果你不能避免它,这里有一个技巧。
将密钥添加到您的 Avatar 组件
const [imageKey, setimageKey] = useState(1);
<Avatar
size="xlarge"
rounded
source={{ uri: imageURL }}
icon={{ name: 'user', type: 'font-awesome' }}
activeOpacity={0.7}
containerStyle={{alignSelf: 'center', backgroundColor: '#89CFF0',
marginTop: 50}}
key={imageKey}
> </Avatar>
并在每次获取新的 imageUrl 时更新密钥:
const uploadImage = async (uri, imageName) => {
const user = firebase.auth().currentUser
const currentUser = user.uid const response = await fetch(uri)
const blob = await response.blob()
const ref = firebase.storage().ref(currentUser + '/profilePicture/'
+ imageName) ref.put(blob) ref.getDownloadURL()
.then((url) => {
setimageURL(url)
setLocalStorage(url)
setimageKey(prev => prev +1)
}
)
}
我有一个状态钩子变量定义如下:
const [imageURL, setimageURL] = useState(null);
我正在使用 expo-image-picker 从我的图库中获取图像并将其上传到 firebase 存储。然后我得到这张图片的 URL 并相应地更新 imageURL 的值。
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log(result);
if (!result.cancelled) {
uploadImage(result.uri, 'Profile-picture')
.then(() => {
console.log('it work')
})
.catch(error => {
console.log('it does not work')
console.error(error)
})
}
}
const uploadImage = async (uri, imageName) => {
const user = firebase.auth().currentUser
const currentUser = user.uid
const response = await fetch(uri)
const blob = await response.blob()
const ref = firebase.storage().ref(currentUser + '/profilePicture/' + imageName)
ref.put(blob)
ref.getDownloadURL()
.then((url) => {
setimageURL(url)
setLocalStorage(url)
})
}
当页面首次加载时,该值为空,因此有一个空白图标。上传图片并获得 URL 后,我的应用程序上的 UI 不会更新以显示新图片。除非我上传另一张新图片,否则它将保持空白。一旦发生这种情况,UI 将更新,但它现在将显示我第一次上传的图像。关于我可能做错了什么的任何想法?
注意:我什至尝试添加一个文本组件并传入 imageURL 变量以显示当前 URL,由于某种原因,此文本会正确更新,但图像不会。 (此处未显示)
return (
<View style={styles.container}>
<KeyboardAwareScrollView
style={{ flex: 1, width: '100%' }}
keyboardShouldPersistTaps="always">
<Avatar
size="xlarge"
rounded
source={{
uri: imageURL
}}
icon={{ name: 'user', type: 'font-awesome' }}
activeOpacity={0.7}
containerStyle={{alignSelf: 'center', backgroundColor: '#89CFF0', marginTop: 50}}
>
</Avatar>
发生这种情况是因为您在子组件中使用了图像源。
使用 imageURL 的初始状态 null 构造子组件。
当父组件中的状态更新时,子组件即 <Avatar>
不知道此更新并且不会重新呈现。不建议将初始状态值传递给子组件。但如果你不能避免它,这里有一个技巧。
将密钥添加到您的 Avatar 组件
const [imageKey, setimageKey] = useState(1);
<Avatar
size="xlarge"
rounded
source={{ uri: imageURL }}
icon={{ name: 'user', type: 'font-awesome' }}
activeOpacity={0.7}
containerStyle={{alignSelf: 'center', backgroundColor: '#89CFF0',
marginTop: 50}}
key={imageKey}
> </Avatar>
并在每次获取新的 imageUrl 时更新密钥:
const uploadImage = async (uri, imageName) => {
const user = firebase.auth().currentUser
const currentUser = user.uid const response = await fetch(uri)
const blob = await response.blob()
const ref = firebase.storage().ref(currentUser + '/profilePicture/'
+ imageName) ref.put(blob) ref.getDownloadURL()
.then((url) => {
setimageURL(url)
setLocalStorage(url)
setimageKey(prev => prev +1)
}
)
}