I have useEffect
which calls an action
from redux
to fetch uploads
useEffect(() => {
getUploads()
}, [getUploads])
However, I only want to fetch when the state changes, not fetch everytime the component renders. I have mapped the state like:
{filteredUploads.map((image, i) => { return (...) })}
I have tried to add getUploads
, filteredUploads
, filteredUploads.length
as dependency array. None of it worked.
My redux-action
:
export const getUploads = () => async dispatch => {
try {
dispatch({ type: 'LOADING', payload: true })
const res = await axios.get('/uploads/myuploads')
dispatch({
type: GETMYUPLOAD_SUCCESS,
payload: res.data
})
} catch (err) {
const error = err.response.data.error[0].msg
dispatch(setAlert(error, 'danger'))
}
}
mapStatetoProps
:
function mapStateToProps(state) {
const { myuploads, searchField } = state.useruploads;
return {
searchField: state.useruploads.searchField,
filteredUploads: myuploads.filter((upload) => upload.caption.toLowerCase().includes(searchField.toLowerCase()))
};
}
To have the useEffect
hook called when state updates, just include the relevant state variables in the dependency array of useEffect
(the second argument passed to useEffect
).
To address useEffect
being called on every render of the component: this is happening because getUploads
gets redefined on every render. To fix this, you can use the useDispatch
redux hook. This is instead of (and assuming you are currently using) mapDispatchToProps
.
Here's a full example:
import { useDispatch } from 'react-redux'
import { getUploads } from "./redux-actions";
const MyComponent = props => {
const dispatch = useDispatch();
const [state, setState] = React.useState({});
useEffect(() => {
dispatch(getUploads());
}, [dispatch, state]);
// rest of component
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With