Closed Je12emy closed 3 years ago
Hi @Je12emy ,
I'm not entirely sure what is going on here, and in order to help you I might need more context.
Where is the variable userProfile
coming from here?
const updateProfile = async () => {
// GET THE AUTH TOKEN
const token = await SecureStore.getItemAsync(SID_KEY);
if (userProfile) {
// DESTRUCTURE NEEDED DATA
const { foto_de_perfil: profileImage, tags } = userProfile;
// PUT REQUEST
await onUpdate(
{ authToken: token as string },
{
profileImage,
tags,
}
);
}
};
It seems like this is the core of the issue you are facing, that the profileImage
destructured and being passed in to onUpdate()
here is stale (old, previous data)?
I suspect that this could be an issue unrelated to Pullstate itself, perhaps just a more regular issue in code that crops up from time to time. But I'd need a little more context to confirm.
Hello, thank you for your response! The variable userProfile
is used for reading the state which allows me to render some properties in my view.
I had to check if it was initialized before mutating it since it could be of type null
, sorry if this problem is unrelated to Pullstate in any way!
And yes, the profileImage
which is being destructured is indeed stale, but it seems like after the onUpdate()
function is done it shows the correct profile image but the put request has already been done with the stale data.
Ahh okay. I think I know what is happening here, and its quite a common issue that people run into with React and hooks- it all boils down to scope.
What I think is happening, is that even though you think you are getting a "fresh" value from:
// TEST FOR GLOBAL STATE
const userProfile = UIProfile.useState();
This userProfile
value was "fresh" only at the time you originally called this part of the code during the original component render.
When you call the updateProfile()
function directly after updating the value inside your store:
const updateProfileImage = async (pickerResult: string) => {
// UPDATE DOES NOT OCCUR ON STORE WITH THE PICKER RESULT URI
UIProfile.update((p) => {
if (p) {
p.foto_de_perfil = pickerResult as string;
}
});
await updateProfile();
};
The function updateProfile()
as it exists right now, is still scoped to the earlier (now stale) value of userProfile
. Its all about references, and what you are referring to inside the current scope and what value it currently holds.
userProfile
is only changed on a future render of the component, and will be inside a new scope of the component then, and the new async functions you defined inside the component that time- hence when you call it again, it will run with that next value again (but still not really fresh, as expected after running your UIProfile.update()
).
What you can do in this case is make the updateProfile()
function refer directly to the current value inside the store by using getRawState()
:
const updateProfile = async () => {
// GET THE AUTH TOKEN
const token = await SecureStore.getItemAsync(SID_KEY);
if (userProfile) {
// DESTRUCTURE NEEDED DATA
const { foto_de_perfil: profileImage, tags } = UIProfile.getRawState();
// PUT REQUEST
await onUpdate(
{ authToken: token as string },
{
profileImage,
tags,
}
);
}
};
This is generally not the best way to do it but yea, its not the end of the world and will work. Another option is to pass in the new value of the profile image as an argument to the function instead.
Hope that helps! Let me know if you still run into any issues.
Hello, I also managed to work around this with useEffect
and a simple shouldUpdate
flag. I'll make sure to give your solution a try.
Sorry if this is not the right place to post this, but I've been trying to implement Pullstate into my RN application in order to reduce the amount of fetch request done throughout the app. For now, I'm fetching some basic data like the user's profile and saving it into the store.
In a "View Profile" screen I'm updating the user's profile photo with expo's image picker and it seems the property is being mutated since the new profile image is rendered as expected (there's a header component which render the profile image too) but when throwing a put request to update the profile, it seems the state before the update to the store was done, is being sent (So the original data which was fetched).
I noticed that after doing the same operation (picking a new profile image) does indeed send the previous intended data too.