Home > Software design >  UseState variable not updating after setting it within a function - React Native
UseState variable not updating after setting it within a function - React Native

Time:03-10

Howcome when i setURL(value) or setURL(val) it doesnt actually set the state?

Only when I press the upload button a second time it sets the state correctly..

First time run:

First time run

My initialized state:

const [URL, setURL] = useState();

The function to get the downloadURL:

await getDownloadURL(fileRef).then((val)=>{
  console.log("From function: " val)
  var value = val;
  setURL(value)

}).catch((error)=>{
  Alert.alert(error.message);
});

Upload button function:

enter image description here

My code:

const AddPost = () => {

const [isEnabled, setIsEnabled] = useState(false);
const toggleSwitch = () => setIsEnabled(previousState => !previousState);
const [Color, setColor] = useState('')
const [Desc, setDesc]= useState('');
const [location, setlocation] = useState('');
const navigation = useNavigation()

const [image, setImage] = useState(null);
const [URI, setURI] = useState(Result);
const [Result, setResult] = useState();
const [URL, setURL] = useState();
const [uploading, setUploading] = useState(false);


const usersCollectionRef = collection(db, "Posts");

  const createPost = async () => 
  {
  setUploading(true); 
  let url = await uploadImageAsync(URI); 
  console.log("from upload btn: " URL)
  await addDoc(usersCollectionRef, { username: auth.currentUser?.email, Colour: Color, Injured: value2, Type: value3, Collar: isEnabled ? 'Yes' : 'No', Welfare: value4, status: value, Description: Desc, picture: URL, location: location })
  Alert.alert("Successfully uploaded!");
  navigation.navigate('MainScreen');
  setUploading(false);
  };
  

  const TakeImage = async () => {
    let result = await ImagePicker.launchCameraAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      quality: 0.6,
    });


    if (!result.cancelled) {
      setImage(result.uri);
      setURI(result.uri);
    }
  };


  const BrowseImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      quality: 0.6,
    });

    console.log(result);

    if (!result.cancelled) {
      
      setImage(result.uri);
      setURI(result.uri);
      
    }
  };

  const uploadImageAsync =async(uri)=> {
    
    const blob = await new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      xhr.onload = function () {
        resolve(xhr.response);
      };
      xhr.onerror = function (e) {
        console.log(e);
        reject(new TypeError("Network request failed"));
      };
      xhr.responseType = "blob";
      xhr.open("GET", uri, true);
      xhr.send(null);
    });
  
    const fileRef = ref(getStorage(), uuid.v4());
    const result = await uploadBytes(fileRef, blob);
    
    let url = await getDownloadURL(fileRef).then((val)=>{
      console.log("From function: " val)
        setURL(val);
        return val;

    }).catch((error)=>{
      Alert.alert(error.message);
    });

    return url;
    
    
  }

CodePudding user response:

Since updating state is an asynchronous method so the state will not get updated immediately. You'll have to work around like this -

 const uploadImageAsync =async(uri)=> {
    // rest of your code
    let url = await getDownloadURL(fileRef).then((val)=>{
      console.log("From function: " val)
        setURL(val);
        return val;

    }).catch((error)=>{
      Alert.alert(error.message);
    });

    return url;
    
  }

And then in your onPress function:-

    const createPost = async () => {
      let url = await  uploadImageAsync(URI);
      // Rest of your code
    }
  • Related