0

Hello I have a problem calling my action using usedispatch

he arrives on my action but for some reason he does not pass on my return. stop here: console.log('here is get all products'); and no go to my getallproducts:

export const getAllProducts = () => {
    console.log('here is get all products');
    return dispatch => {
        dispatch(isLoadingFetch());
        api.get('/products')
        .then( response => { dispatch(FetchSucess(response.data))})
        .catch( err => { dispatch(FetchFailed(err.message));});
    }
}

my reducer:

import {FETCH_FAIL, FETCH_SUCESS, FETCH_LOADING} from '../../actions/fetch/actionType';

const initialState = {
    loading: false,
    products: [],
    filteredProducts: [],
    fn:[],
    mw:[],
    ft:[],
    ww:[],
    bs:[],
    stattrek:[],
    normal:[],
    error: null
  };

  export default function productReducer(state = initialState, action) {
    switch (action.type) {
      case FETCH_LOADING:
        return {
          ...state,
          loading: true
        };
      case FETCH_SUCESS:
        return {
          ...state,
          loading: false,
          error: null,
          filteredProducts: action.data.listProducts,
          products: action.data.listProducts,
          fn: action.data.fn,
          mw: action.data.mw,
          ft: action.data.ft,
          ww: action.data.ww,
          bs: action.data.bs,
          stattrek: action.data.listProducts.filter(value=> value.id_types === 1),
          normal: action.data.listProducts.filter(value=> value.id_types === 2)
        };
      case FETCH_FAIL:
        return {
          ...state,
          loading: false,
          error: action.error
        };
      default:
        return state;
    }
  }

my container:

import styles from "../assets/cardStyle";
import { useDispatch, useSelector } from "react-redux";
import {useEffect, useCallback} from "react";
import { getAllProducts } from '../store/actions/fetch/index'
const useStyles = makeStyles(styles);

export default function Cards() {

    const classes = useStyles();

    const dispatch = useDispatch();

    const loadProducts= useCallback(async () => {
        dispatch(getAllProducts());
        }, [dispatch]);

        useEffect(() => {
            loadProducts();
            }, [loadProducts]);

    const products = useSelector(state => {
    })

    products.map(product=>(
        <div>
        <Container fixed>
            <Grid container direction="row" >
                <Grid item xs={3}>
                    <Card className={classes.card}>
                        <CardContent className= {classes.cardCarousel}>
                            <Typography variant="body2" color="textSecondary" component="p">
                                This impressive paella is a perfect party dish and a fun meal to cook together with your
                                guests. Add 1 cup of frozen peas along with the mussels, if you like.
                            </Typography>
                        </CardContent>
                    </Card>

                </Grid>
            </Grid>
        </Container>
    </div> 
    ))

    return (
        {products}
    );
}

I can't imagine where I'm going wrong it calls my getAllProducts but does not enter my redux

2
  • dispatch is not available in the scope of that function. Pass it to the function as an argument. Commented Dec 7, 2019 at 13:32
  • how i can make this? i need pass on my useDispatch? Commented Dec 7, 2019 at 13:34

2 Answers 2

1

If you need to create higher-order functions like you do in getAllProducts() returning another function you need to call that function and pass dispatch as the first argument.

const loadProducts= useCallback(() => {
    /**
     * first call returns a function from getAllProducts
     * second will call it and we pass dispatch as the first argument 
     */ 
    getAllProducts()(dispatch);
}, [dispatch, getAllProducts]);    

Or you can simply pass dispatch in the first function and call it right away:

export const getAllProducts = (dispatch) => {
    console.log('here is get all products');
    dispatch(isLoadingFetch());
    // fetching data
    api.get('/products')
        .then( response => { dispatch(FetchSucess(response.data))})
        .catch( err => { dispatch(FetchFailed(err.message));});
}
// ...
const loadProducts= useCallback(() => {
    /**
     * first call pass dispatch as the first argument
     */ 
    getAllProducts(dispatch);
}, [dispatch, getAllProducts]);
Sign up to request clarification or add additional context in comments.

5 Comments

thank you bro, could you ask me one more question? I save my state with: const products = useSelector (state => state.data) but when i try to give the .map i have error of .map is not function
i think the problem might be you yet haven't received the data and it's undefined you can check that then call .map on it.
The problem was, I wasn't passing an array but now I passed an array and got this error: Error: Objects are not valid as a React child (found: object with keys {id, name, float, price, id_sub, subcategory, id_types, type, id_ext, outer, img, description}). If you meant to render a collection of children, use an array instead.
You're trying to render an object as a child. While in dev you can just wrap it in JSON.stringify(product) to see the content.
Whats the win here using useCallback? Why do you need a stable reference here?
1

You could just go ahead and import the useDispatch hook in the file located here ../store/actions/fetch/index

similar to the way you did in your other file

4 Comments

Instead of using useDispatch in my container use in my action?
Could you give me an example?
Yes like you use the dispatch in your action that way your container focus on component logic.
Don't do this. Hooks are supposed to be called unconditionally at the beginning of each components, if at some point you need to change your logic of when to call getAllProducts() then useDispatch() will be called conditionally and will definitely break your logic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.