I've been attempting to find discussions about this for over a week now, but most issues seem related to trouble persisting through a refresh, while I'm having state troubles without refreshing, so I'm not getting much of anywhere with it.
I'm attempting to load a gallery of images after a user logs in. The login is functioning properly--updates the state with a reducer and pushes from /login to /gallery and I can see in the inspector that the user ID updates from null to a value.
At /gallery I attempt to retrieve some data through axios asynchronously. It's a POST request so that I can send the user's ID in the body rather than the url/using params.
On initial login, state.images doesn't update and throws this error: "data: "Cast to string failed for value "{ user: '60fc726d827a4e3daff47619' }" (type Object) at path "user" for model "Upload"" " Relative to my database/models: I've tried adjusting type on the model, both the $type approach and adjusting for a String that is an array, the former caused errors large enough for the page not to load, the latter affected no discernible changes.
If I reload the page, everything works and the images load. If I click from gallery to home and then back to gallery again, nothing changes in the state. I have no idea if this is an issue with my amateur async function structure, my mongodb setup, my reducer, the axios post itself, or something else entirely.
I've read that pretty much everything needs to be lined up inside of useEffect() but I've had absolutely no luck getting that to function either.
The whole of the code is at https://github.com/polysnacktyl/react-foraging, but here's the (seemingly) most relevant:
Login
function Login() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const { getLoggedIn } = useContext(AuthContext);
const { dispatch } = useContext(Context);
const history = useHistory();
async function login(e) {
e.preventDefault();
try {
const { data } = await axios.post('http://localhost:3000/auth/login', {
email,
password
});
await getLoggedIn();
dispatch({
type: 'login',
payload: { user: data._id }
})
window.localStorage.setItem('user', JSON.stringify(data._id))
history.push('/gallery');
} catch (err) {
console.error(err);
}
}
return (... and so forth
Image Gallery
const { state, dispatch } = useContext(Context);
const [isLoading, setLoading] = useState(true);
const [images, setImages] = useState({ images: [] });
const user = state.user;
const success = async () => {
try {
const res = await axios.post('http://localhost:3000/auth/mine', { user });
dispatch({
type: 'fetchSuccess',
payload: { images: res.data }
})
setImages(res.data);
} catch (err) { console.log(err.response) }
}
const fail = (error) =>
dispatch({
type: 'fetchFail',
payload: { error: error.message }
});
function loadImages() {
dispatch({ type: 'fetchImages' });
setTimeout(async () => {
try {
await success();
setLoading(false)
} catch (error) {
await fail(error);
}
}, 1000);
}
useEffect(() => {
loadImages()
//eslint-disable-next-line
}, [])
if (isLoading) {
return (<div className='loading'>...loading</div>)
} else {
return (...and so on