Search code examples
reactjsreact-reduxredux-thunk

Not dispatching thunk action every time


I have a list of invoice cards when a user clicks on a single card it should open something like a modal with data related to that invoice like on the image.

enter image description here

The problem is that I sometimes get a blank modal and after clicking it back and forth a couple of time I get the data again: enter image description here

This is my action for dispatching payout by id:

export const getPayoutById = (id) => (dispatch) => {
  dispatch({ type: GET_PAYOUT_BY_ID_LOADING });
  paypalUrl
    .get(Constants.PAYOUT + `/${id}`, { headers })
    .then(({ data }) => {
      dispatch({ type: GET_PAYOUT_BY_ID, payload: { payout: data } });
    })
    .catch((error) => {
      console.error(error);
      dispatch({ type: GET_PAYOUT_BY_ID_ERROR, payload: { error } });
    });
};

This is a reducer:

 case GET_PAYOUT_BY_ID_LOADING:
      return {
        ...state,
        loading: true,
      };
    case GET_PAYOUT_BY_ID:
      return {
        ...state,
        loading: false,
        payout: action.payload.payout,
      };
    case GET_PAYOUT_BY_ID_ERROR:
      return {
        ...state,
        loading: false,
        payout: {},
        error: action.payload.error,
      };

And this is the component where I'm dispatching action:

const AllPayouts = ({ invoices, tabs }) => {
  const dispatch = useDispatch();
  const { payouts, payout, loading } = useSelector(
    (state) => state.payoutReducers
  );

  const [invoice, setInvoice] = useState(false);

  useEffect(() => {
    dispatch(getPayouts());
  }, []);


  const openInvoice = (e) => {
    e.preventDefault();
    dispatch(getPayoutById(e.target.id));
    setInvoice(true);
  };

  return (
    <>
    
      <PayoutList>
        {payouts?.length > 5 && (
          <div className='payout-pagination'>
            <Pagination
              classesChunk={classesChunk}
              totalItems={invoices.length}
              changePage={changePage}
            />
          </div>
        )}
        {loading && <Loader />}
        {!loading &&
          payouts &&
          payouts.map((invoice) => (
            <InvoiceCard
              id={invoice.id}
              key={invoice.id}
              startDate={moment(invoice.invoiceStartDate).format('MMM Do')}
              endDate={moment(invoice.payoutDate).format('MMM Do, YYYY')}
              classes={invoice.payoutItemDTOs.length}
              status={invoice.needsPay ? 'arrival' : 'paid'}
              openInvoice={openInvoice}
            />
          ))}
      </PayoutList>
      {payout!== undefined && (
        <Payment
          id={payout.id}
          open={invoice}
          payout={payout}
          loading={loading}
          onClose={() => setInvoice(false)}
        />
      )}
    </>
  );
};

Solution

  • I figure out why sometimes works and sometimes not. It depends where I click on the card.

    It was because I was setting an id with e.target.id:

    dispatch(getPayoutById(e.target.id));
    

    and the wrapping div has it .... so when I click on a title, the price for example it has no id, and nothing is shown. :

    <h5 class="bold subtitles">Dec 2nd - Dec 16th, 2020</h5>
    

    That is why sometimes works and sometimes not.

    I fixed it with setting an id with e.currentTarget.id instead of e.target.id

    dispatch(getPayoutById(e.currentTarget.id));