Reputation: 65
I am dispatching action addProducts on every mount of the ProductList component whereas i want to dispatch the action one timeusing useEffect hook and store the data in the redux and then use it.
Below are my actions file and ProductList component file.
actions.js file
export const addProducts = () => async (dispatch) => {
let Products = await axios.get("https://api.npoint.io/2a4561b816e5b6d00894");
return dispatch({
type: ADD_PRODUCTS,
payload: Products.data,
});
};
ProductList.js component file
import { addProducts } from "../actions/Index";
const ProductList = () => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(addProducts());
},[]);
const Products = useSelector((state) => state.products);
console.log(Products)
Upvotes: 2
Views: 85
Reputation: 1378
You want to check if products are already in redux with an if(!products){...}
e.g.
const addProducts = () => async (dispatch) => {
let Products = await axios.get("https://api.npoint.io/2a4561b816e5b6d00894");
return dispatch({
type: ADD_PRODUCTS,
payload: Products.data,
});
};
const ProductList = () => {
const dispatch = useDispatch();
const products = useSelector((state) => state.products);
useEffect(() => {
if (!products) {
dispatch(addProducts());
}
},[dispatch]);
return <p>foo</p>
}
Upvotes: 2
Reputation: 39340
You could just dispatch the action in the component but in the thunk action do nothing if products are available:
export const addProducts = () => async (
dispatch,
getState,//thunk also get a getState function
) => {
//you should write a dedicated selector function so you could do:
// const productsInState = selectProducts(getState())
const productsInState = getState().products
//whatever would make state.products available
// reducers are missing in your question
if(productsInState){
//do nothing if products are already in state
return;
}
let Products = await axios.get(
'https://api.npoint.io/2a4561b816e5b6d00894',
);
return dispatch({
type: ADD_PRODUCTS,
payload: Products.data,
});
};
In your component you can just dispatch on each render, if your page has multiple components dispatching this action then you could make a grouped action.
Upvotes: 2
Reputation: 6752
export const addProducts = () => async dispatch => {
dispatch({
type: ADD_PRODUCTS_START,
payload: { loading: true },
});
const Products = await axios.get(
'https://api.npoint.io/2a4561b816e5b6d00894'
);
dispatch({
type: ADD_PRODUCTS_SUCCESS,
payload: { products: Products.data, loading: false },
});
};
const ProductList = ({ products, loading }) => {
useEffect(() => {
if (!products && !loading) {
dispatch(addProducts());
}
}, []);
};
const mapStateToProps = ({ products: { data, loading } }) => ({ products: data, loading });
Upvotes: 1