0

When calling setImage(result.uri); console.log(image) logs null when it should show me the new image uri. Interestingly the error shows up as

TypeError: null is not an object (evaluating 'props.route.params.uid')

after pickImage is called even though before it's called it has no problem evaluating it and displaying it. If I remove props.navigation.navigate("Save", image, album); and pickImage is called again, this time console.log(image); will show me the uri for the image picked earlier.

const [album, setAlbum] = useState("");
const [hasGalleryPermission, setHasGalleryPermission] = useState(null);
const [image, setImage] = useState(null);

useEffect(() => {
setAlbum(props.route.params.uid);
(async () => {
  const galleryStatus =
    await ImagePicker.requestMediaLibraryPermissionsAsync();
  setHasGalleryPermission(galleryStatus.status === "granted");
})();
}, []);

const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
  mediaTypes: ImagePicker.MediaTypeOptions.Images,
  allowsEditing: true,
  aspect: [1, 1],
  quality: 1,
});
console.log(result);

if (!result.cancelled) {
  setImage(result.uri);
  console.log(result.uri);
  console.log(image);
  console.log(album);
  props.navigation.navigate("Save", image, album);
}

};

1 Answers1

0

It is working as expected. setState (setImage) is asynchronous. console.log(image); logs null the first time because the setState is not done executing yet. On the second run of console.log, the previous async setState has already finished and it is still expected to log the previous data because it was not overwritten yet by the second async setState call.

I'm assuming you want to perform props.navigation when the image changes?

  • You can wrap your setState in a function returning a promise so you can then await its execution until data is resolved.
  • You can also add a callback function on your setState which will be called after your state has been updated. Note that this is only for class component. Check the last option if you are using functional component.

setImage(result.uri, () => props.navigation.navigate("Save", image, album));

  • Personally, I prefer useEffect in such cases where in I'd like to trigger a specific logic when something else changes. In your case, I will move props.navigation function to be called inside a useEffect hook where the dependency is when image changes:

useEffect(() => {props.navigation.navigate("Save", image, album); }, [image])

EDIT: this might be a duplicate:How to use `setState` callback on react hooks if not, some answers there will give you more idea how state works.

lemongrab
  • 9
  • 3