【问题标题】:declaring variables faster than setState比 setState 更快地声明变量
【发布时间】:2020-01-20 13:14:20
【问题描述】:

我和我的团队正在制作一个显示个人资料图片和简历的个人资料页面。我们使用 expo-image-picker 库让用户选择他们想要的图像并在应用程序上显示图像。我还想将图像上传到存储员工图像的 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)
      })
    }
  }

按下“保存”按钮后,我想将图像上传到 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 的状态是本地文件。只有在我再次按下保存按钮后,警报才会将 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 是异步的,因此在uploadImage 函数中将警报紧随其后不会显示其设置的真实值。将您的警报放在不在同一个 JS 线程中的其他地方,一旦setState 实际完成,您将看到正确的值(就像在您返回组件之前在您的渲染函数中一样。您第二次按下时看到它的原因保存是因为它在新状态值设置(并且完成)之前向您显示先前状态的值
  • 那么,有没有办法解决这个问题?
  • 我把警报放在那里是因为当它调用 updateProfileData(params) 时,imageUrl 一直是本地文件,我希望 params.ImageUrl 成为 s3 链接。有没有办法得到这个?

标签: javascript react-native redux expo


【解决方案1】:

问题是当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);
        })
      })
  }

【讨论】:

    猜你喜欢
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多