javascript - 比 setState 更快地声明变量
问题描述
我和我的团队正在制作一个显示个人资料图片和简历的个人资料页面。我们使用 expo-image-picker 库让用户选择他们想要的图像并在应用程序上显示图像。我还想将图像上传到存储员工图像的 s3。我现在面临的问题是 params.ImageUri 给了我本地文件而不是 s3 链接。这就是我的功能的样子。
我有一个 selectImage() 函数,它将触发用户从他们的图库中选择图像。然后数据将存储在this.state.items[0].imageUrl中,这是来自 Web API 的数据。我调用这个函数后,this.state.items[0].imageUrl的值就是本地文件。当用户按下他们的Profile Picture时调用此函数。
selectImage = async () => {
const cancelImageUrl = this.state.items[0].imageUrl
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1
});
const file = {
uri: result.uri,
name: 'IMG_' + Math.random(4000),
type: 'image/jpg'
}
if (!result.cancelled) {
this.setState({
items: this.state.items.map((item, i) =>
i == 0 ?
{ ...item, imageUrl: file.uri } : item),
file: file
})
}
else {
this.setState({
items: this.state.items.map((item, i) =>
i == 0 ?
{ ...item, imageUrl: cancelImageUrl } : item)
})
}
}
按下保存按钮后,我想将图像上传到 s3,将文件保存在云中,以便用户在打开应用程序时能够看到它。在这里,当我记录items[0].imageUrl的状态时,它会显示 s3 链接。
uploadImage = () => {
let file = this.state.file;
let config = this.state.config;
RNS3.put(file, config)
.then((response) => {
console.log(response.headers.Location);
this.setState({
items: this.state.items.map((item, i) =>
i == 0 ?
{ ...item, imageUrl: response.headers.Location } : item)
})
console.log('This is the state of items[0].imageUri ' + this.state.items[0].imageUrl)
})
}
所以,在这里我决定首先将图像上传到 s3 并将items[0].imageUrl的状态设置为链接。然后将 params 的值设置为 imageUrl,然后通过调用 updateProfileData(params) 更新 WebAPI。我目前面临的问题是,当我按下保存时,屏幕上弹出的警报显示items[0].imageUrl的状态是本地文件。只有在我再次按下 Save 按钮后,警报才会将items[0].imageUrl的状态显示为 s3 链接。
<TouchableOpacity style={styles.button}
onPress={() => {
this.uploadImage();
let params = {
ImageUrl: this.state.items[0].imageUrl,
EmployeeBio: this.state.items[0].employeeBio
};
alert('This is params, ' + params.ImageUrl);
this.updateProfileData(params);
}}>
<View>
<Text style={styles.text}>Save</Text>
</View>
</TouchableOpacity>
我和我的团队无法解决这个问题...感谢您的帮助!
解决方案
setState
问题是您在异步函数时在同步 JS 线程中做事。解决这个问题的方法是在setState
函数中使用回调参数(传入的第二个参数,将在设置状态后执行)并在updateProfileData
那里执行您的代码。
请参阅此处了解解释 - https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296
因此,要解决您的问题,您应该执行以下操作:
零件
<TouchableOpacity style={styles.button}
onPress={() => this.uploadImage()}>
<View>
<Text style={styles.text}>Save</Text>
</View>
</TouchableOpacity>
上传图片
uploadImage = () => {
let file = this.state.file;
let config = this.state.config;
RNS3.put(file, config)
.then((response) => {
console.log(response.headers.Location);
this.setState({
items: this.state.items.map((item, i) =>
i == 0 ?
{ ...item, imageUrl: response.headers.Location } : item)
},
// This is your callback
() => {
let params = {
ImageUrl: this.state.items[0].imageUrl,
EmployeeBio: this.state.items[0].employeeBio
};
alert('This is params, ' + params.ImageUrl);
this.updateProfileData(params);
})
})
}
推荐阅读
- hive - Hive ACID 表抛出错误 FAILED: UnsupportedOperationException openTxn is not supported in aws EMR
- gitlab - gitlab globbing 表达式不匹配
- swift - Swift 错误:无法从“A”转换为“A?” 使用泛型时
- excel - 只要按下多个键,Vba Excel就会在用户窗体中显示一个按钮
- ios - 如何修改 UIDatePicker 中的“shortWeekdaySymbols”?
- c++ - 使用 ofstream 时崩溃
- git - 如何获取对 Git 推送进行身份验证的用户(到 BitBucket 存储库)
- reactjs - react-i18next 翻译不适用于传递的 Prop 元素
- python - 在 Pycharm 上安装 KIvy。给出窗口错误
- android - Android即使启用也无法获取位置