I recently started learning React, so I'm trying to make a CRUD but I am facing a problem with the useContext and useEffect, I am currently working on the edit page and I think I almost have it, the problem is that when I use the useEffect hook is validating that I have a data key on my state from my useContext, the problem is that it is true instead of being false, because it actually exists a data key from the index page which render all my albums and when I click on edit is bringing the same array of data to the edit page, so it turns beign true the condition.
I tried to set the data: null
on my reducer's showRequest function, but it still does not work so it is not setting the values to my form as it should be, a single album object, not an array of albums. I hope I've made myself clear as my english is not my native language. Thank you in advance. I let you the code.
As you can see is bringing me the data as an array therefore the conditional that I commented on the code below, is trying to set the form with that array of albums instead of just waiting to fetch just an album by the id
AlbumsEdit.jsx `
export const AlbumsEdit = () => {
const { id } = useParams();
const navigate = useNavigate();
const { state, show, update } = useContext(AlbumContext);
const { form, setForm, handleOnChange } = useForm({
image: '',
album_name: '',
artist: '',
released: '',
});
console.log(state);
useEffect(() => {
show(id);
if (!!state.data) // The conditional I spoke previously
setForm(state.data);
}, []);
const handleUpdateAlbum = () => {
update(id, form);
navigate(-1);
}
if (state.isLoading) return <Spinner />
if (state.errors) return <Typography>{state.errors.message}</Typography>
if (!!state.data)
return (
<>
<AlbumsForm title="Edit album" image={form.image} album_name={form.album_name} artist={form.artist} released={form.released} handleOnChange={handleOnChange} />
<Grid container sx={{ mt: 2 }} justifyContent='end'>
<Grid item>
<Button variant='contained' onClick={handleUpdateAlbum}>Update album</Button>
</Grid>
</Grid>
</>
)
}
`
AlbumProvider.jsx `
const initialState = {
data: null,
isLoading: false,
errors: null
}
export const AlbumProvider = ({ children }) => {
const [state, dispatch] = useReducer(albumReducer, initialState);
const index = async () => {
let action = {
type: albumTypes.indexRequest
}
dispatch(action);
const { data, status } = await fetchAlbums();
if (status == 200) {
let action = {
type: albumTypes.indexSuccess,
payload: data
}
dispatch(action);
return;
}
// If the status is different from 200
action = {
type: albumTypes.indexFailure,
payload: data
}
dispatch(action);
}
const show = async id => {
let action = {
type: albumTypes.showRequest
}
dispatch(action);
const { data, status } = await fetchAlbumById(id);
if (status == 200) {
let action = {
type: albumTypes.showSuccess,
payload: data
}
dispatch(action);
return;
}
// If the status is different from 200
action = {
type: albumTypes.showFailure,
payload: data
}
dispatch(action);
}
return (
<AlbumContext.Provider value={{ state, index, create, show, destroy, update }}>
{children}
</AlbumContext.Provider>
)
`
albumReducer.js
import { albumTypes } from './albumTypes';
export const albumReducer = (state, action) => {
switch (action.type) {
// Index
case albumTypes.indexRequest:
return {
...state,
isLoading: true
}
case albumTypes.indexSuccess:
return {
...state,
data: action.payload,
isLoading: false,
}
case albumTypes.indexFailure:
return {
...state,
errors: action.payload,
isLoading: false
}
// Show
case albumTypes.showRequest:
return {
...state,
data: null, //the thing I tried to clear the data from the index page
isLoading: true
}
case albumTypes.showSuccess:
return {
...state,
data: action.payload,
isLoading: false
}
case albumTypes.showFailure:
return {
...state,
errors: action.payload,
isLoading: false
}