Javascript 声明变量的速度比setState快

Javascript 声明变量的速度比setState快,javascript,react-native,redux,expo,Javascript,React Native,Redux,Expo,我和我的团队正在制作一个个人资料页面,显示个人资料图片和个人简历。我们使用expo图像选择器库为用户选择他们想要的图像,并在应用程序上显示图像。我还想将图像上传到s3,在s3中存储员工的图像。我现在面临的问题是params.ImageUri给我的是本地文件,而不是s3链接。这就是我的函数的样子 我有一个selectImage()函数,它会触发用户从他们的图库中选择图像。然后数据将存储在this.state.items[0].imageUrl中,这是来自Web API的数据。调用此函数后,this

我和我的团队正在制作一个个人资料页面,显示个人资料图片和个人简历。我们使用expo图像选择器库为用户选择他们想要的图像,并在应用程序上显示图像。我还想将图像上传到s3,在s3中存储员工的图像。我现在面临的问题是params.ImageUri给我的是本地文件,而不是s3链接。这就是我的函数的样子

我有一个selectImage()函数,它会触发用户从他们的图库中选择图像。然后数据将存储在this.state.items[0].imageUrl中,这是来自Web API的数据。调用此函数后,this.state.items[0].imageUrl的值是本地文件。当用户按下其配置文件图片时,调用此函数

  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)
      })
    }
  }
按下Save按钮后,我想将图像上传到s3,将文件保存在云中,以便用户在打开应用程序时能够看到它。在这里,当我记录项[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)
      })
  }
            <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>
因此,我决定首先将图像上传到s3,并将项[0]的状态设置为链接的imageUrl。然后将params的值设置为imageUrl,然后通过调用updateProfileData(params)更新WebAPI。我目前面临的问题是,当我按Save时,屏幕上弹出的警报显示项[0]的状态。imageUrl是本地文件。只有在我再次按下“保存”按钮后,警报才会将项[0]的状态显示为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)
      })
  }
            <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>
{
这是uploadImage();
设params={
ImageUrl:this.state.items[0]。ImageUrl,
EmployeeBio:此.state.items[0]。EmployeeBio
};
警报(“这是参数,+params.ImageUrl”);
此.updateProfileData(参数);
}}>
拯救

我和我的团队无法解决这个问题。。。谢谢你的帮助

问题在于,当
setState
是一个异步函数时,您正在同步JS线程中执行操作。解决此问题的方法是在
setState
函数中使用回调参数(传入的第二个参数,将在设置状态后执行),然后在那里执行
updateProfileData
代码

有关说明,请参见此处-

因此,要解决您的问题,您应该执行以下操作:

组件

<TouchableOpacity style={styles.button}
    onPress={() => this.uploadImage()}>
   <View>
        <Text style={styles.text}>Save</Text>
   </View>
</TouchableOpacity>

你好这可能是因为
setState
是异步的,因此将警报放在
uploadImage
函数的后面不会显示其设置的真实值。将您的警报放在其他不在同一JS线程中的地方,一旦
setState
实际完成,您将看到正确的值(就像在返回组件之前的渲染函数中一样。第二次按save时看到它的原因是,它显示了在设置新状态值(并完成)之前的前一状态值)那么,有没有办法解决这个问题呢?我把警报放在那里是因为当它调用
updateProfileData(params)
时,imageUrl一直是本地文件,我希望
params.imageUrl
成为s3链接。有没有办法得到这个链接?