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:
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:
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
}