Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dispatch an action on page load in react-redux?

I have to display a table with lot of data. There is a pagination button which display 10 record per page. I have one button called "FETCH" on-click of it table is populating. How do load my table on load of the page.

action.js

import fetch from 'isomorphic-fetch';
export const ADD_BENEFICIARY = 'ADD_BENEFICIARY';
export const REMOVE_BENEFICIARY = 'REMOVE_BENEFICIARY';

export const ADD_PLAN_TO_COMPARE = 'ADD_PLAN_COMPARE';
export const REMOVE_PLAN_FROM_COMPARE = 'REMOVE_PLAN_COMPARE';
export const SHOW_PLAN_COMPARE = 'SHOW_PLAN_COMPARE';

export const NEXT_PAGE_PLAN_LIST = 'NEXT_PAGE_PLAN_LIST';
export const PREV_PAGE_PLAN_LIST = 'PREV_PAGE_PLAN_LIST';
export const REQUEST_PAGE_PLAN_LIST = 'REQUEST_PAGE_PLAN_LIST';
export const RECEIVE_PAGE_PLAN_LIST = 'RECEIVE_PAGE_PLAN_LIST';

export const showNextPageOfPlans = () => {

  return {
    type: NEXT_PAGE_PLAN_LIST
  }
}

export const showPreviousPageOfPlans = () => {

  return {
    type: PREV_PAGE_PLAN_LIST
  }
}

export const requestPageOfPlans = (startIdx, pageSize) => {

  return {
    type: REQUEST_PAGE_PLAN_LIST,
    start: startIdx,
    pageSize: pageSize
  }
}

export const receivePageOfPlans = (startIdx, json) => {

  return {
    type: RECEIVE_PAGE_PLAN_LIST,
    start: startIdx,
    plans: json
  }
}


export const fetchPlans = (startIdx, pageSize) => {

    var str = sessionStorage.getItem('formValue'); //JSON.stringify(formValues);

  return function (dispatch) {
    dispatch(requestPageOfPlans(startIdx, pageSize));
    return fetch('http://172.16.32.57:9090/alternatePlans/plans/list/', {method: 'post', body: str, headers: new Headers({'Content-Type': 'application/json'})  })
      .then(response => response.json())
      .then(json =>
        dispatch(receivePageOfPlans(startIdx, json))
      )
  }
}

reducer.js

import { REQUEST_PAGE_PLAN_LIST, RECEIVE_PAGE_PLAN_LIST,
         NEXT_PAGE_PLAN_LIST, PREV_PAGE_PLAN_LIST } from './actions';

const initialPaging = {

  startIndex: 0,
  lastIndex: 0,
  pageSize: 10
}

const paging = (state = initialCurrentPage, action) => {

  switch (action.type) {

    case NEXT_PAGE_PLAN_LIST:

      if (state.startIndex+state.pageSize <= state.lastIndex) {

        return { ...state, startIndex: state.startIndex+state.pageSize };
      }
      else {

        return state;
      }

    case PREV_PAGE_PLAN_LIST:

      if (state.startIndex-state.pageSize >= 0) {

        return { ...state, startIndex: state.startIndex-state.pageSize };
      }
      else {

        return state;
      }

    case REQUEST_PAGE_PLAN_LIST:

      return { ...state, isFetching: true };

    case RECEIVE_PAGE_PLAN_LIST:

      return { ...state, isFetching: false };

    default:
      return state;
  }

}

var initialPlans = [];

const plans = (state = initialPlans, action) => {

  switch (action.type) {

    case RECEIVE_PAGE_PLAN_LIST:
      return action.plans.plans;

    default:
      return state;
  }
}


const allReducers = (state = {}, action) => {

  let items = plans(state.plans, action);
  return {
    plans: items,
    paging: paging({ ...initialPaging, ...state.paging, lastIndex: items.length-1 }, action)
  }
}

export default allReducers;

P.S. I am new to react-redux. Official Documentation is good but very less explanation is given.

like image 861
Raj Rj Avatar asked Aug 25 '16 03:08

Raj Rj


People also ask

How do I dispatch actions in Redux functional component?

There are two ways to dispatch actions from functional components: Using mapDispatachToProps function with connect higher order component, same as in class based components. Using useDispatch hook provided by react-redux . If you want to use this hook, then you need to import it from the react-redux package.

How do you dispatch in Redux?

UseSelector and useDispatch in React Redux It takes in a function argument that returns the part of the state that you want. The equivalent of map dispatch to props is useDispatch. We can invoke useDispatch and store it to a variable, dispatch. Dispatch will work with the allActions imported from the actions folder.

How do you call an action in react Redux?

You can dispatch an action by directly using store. dispatch(). However, it is more likely that you access it with react-Redux helper method called connect(). You can also use bindActionCreators() method to bind many action creators with dispatch function.


1 Answers

You call it from the componentDidMount() of the react component for your page, or wherever it makes sense. So in that component file:

import { requestPageOfPlans } from 'actions';
import React from 'react';
import { connect } from 'react-redux';

class MyComponent extends React.Component {
  componentDidMount() {
    this.props.requestPageOfPlans();
  }
}

export default connect((state) => state, { requestPageOfPlans })(MyComponent);

So the key here is the connect setup. The first parameter is how you wish to transform state (your reducers) into data for props. Adjust that as you need to. The second one is what actions you wish to bind. You can also import dispatch manually, but I personally like this pattern. It sets up the actions as props on the component, and you can call it that way. Just pass the arguments to it as you need to. This page here: https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options explains the connect function in more detail.

Edit

Given you're paginating on the front end, you'll need to adjust the connect mapStateToProps function to pass the pagination data down to the component, and then loop through it to display what you need. Personally I would do the pagination on the back end, and just do new requests for each page. Depends on how many records you're expecting to have.

So in the connect do something like this:

export default connect((state) => {
  return {
    startIndex: state.paging.lastIndex,
    pageSize: state.paging.pageSize,
    lastIndex: state.paging.lastIndex,
    plans: state.plans
  };
}, { requestPageOfPlans })(MyComponent);

Then in your component, loop through the plans using those indexes:

 render() {
   const plans = [];
   const maxIndex = Math.min(this.props.startIndex + this.props.pageSize, this.props.lastIndex);
   for (let i = this.props.startIndex || 0; i < maxIndex; i++) {
     const plan = this.props.plans[i];
     plans.push(<Plan key={plan.id} plan={plan} />);
   }

   return (
     <ul>{plans}</ul>
   );
 }

Making some assumptions again on how you plan to render it, if you have a component called Plan, etc. But that's roughly how you can work with it.

like image 54
agmcleod Avatar answered Oct 09 '22 09:10

agmcleod