How to cache API response and use it later in react & redux?

后端 未结 3 759
再見小時候
再見小時候 2021-02-05 17:47

In my React based application, there is a rest API call which fetches all the data in one shot which is needed for the whole page. The response has data which can be used in a p

相关标签:
3条回答
  • 2021-02-05 18:11

    As I guessed you are using redux for state management. And You want to cache api calls for efficient controll state changes for avoiding rerendering Components, unnecessarry API calls and being friendly for Mobile Users (with avoiding fetchig same data(not changed) multiple time). If so -> then you can use ready solution for it.

    redux-cache. please visit below link for additional information and investigate caching mechanizm briefly -> when you need cache data and when you need evict cache.

    https://github.com/JumboInteractiveLimited/redux-cache

    How do I implement caching in Redux?

    0 讨论(0)
  • 2021-02-05 18:24

    you can cache in HDD or RAM.

    • HDD = e.g. localStorage
    • RAM = application state, e.g. redux store.

    For localStorage you can use my little plugin for this: https://www.npmjs.com/package/localstorage-ttl

    In app state (RAM) - fire action to fetch data, use redux-thunk, redux-saga or similar to make a call and with reducer save data in the store. Retrieve data from store.

    https://github.com/gaearon/redux-thunk https://github.com/redux-saga/redux-saga

    0 讨论(0)
  • 2021-02-05 18:25

    You could choose a redux-cached-api-middleware (disclaimer: I'm the author of this library), that's especially built for such cases.

    Here's an example that might fit your case:

    import React from 'react';
    import PropTypes from 'prop-types';
    import { connect } from 'react-redux';
    import api from 'redux-cached-api-middleware';
    import Dropdown from './Dropdown';
    import Error from './Error';
    
    class ExampleApp extends React.Component {
      componentDidMount() {
        this.props.fetchData();
      }
    
      render() {
        const { result } = this.props;
        if (!result) return null;
        if (result.fetching) return <div>Loading...</div>;
        if (result.error) return <Error data={result.errorPayload} />;
        if (result.successPayload) return <Dropdown items={result.successPayload} />;
        return <div>No items</div>;
      }
    }
    
    ExampleApp.propTypes = {
      fetchData: PropTypes.func.isRequired,
      result: PropTypes.shape({}),
    };
    
    const CACHE_KEY = 'GET/items';
    
    const enhance = connect(
      state => ({
        result: api.selectors.getResult(state, CACHE_KEY),
      }),
      dispatch => ({
        fetchData() {
          return dispatch(
            api.actions.invoke({
              method: 'GET',
              headers: { Accept: 'application/json' },
              endpoint: 'https://my-api.com/items/',
              cache: {
                key: CACHE_KEY,
                strategy: api.cache
                  .get(api.constants.SIMPLE_SUCCESS)
                  .buildStrategy(),
              },
            })
          );
        },
      })
    );
    
    export default enhance(ExampleApp);
    

    It will fetch from API only once, and whenever you call fetchData it will return data from the cache, even if the call is from another component.

    The setup for this library is as follows:

    import { createStore, combineReducers, applyMiddleware } from 'redux';
    import thunk from 'redux-thunk';
    import { apiMiddleware } from 'redux-api-middleware';
    import api from 'redux-cached-api-middleware';
    import reducers from './reducers';
    
    const store = createStore(
      combineReducers({
        ...reducers,
        [api.constants.NAME]: api.reducer,
      }),
      applyMiddleware(thunk, apiMiddleware)
    );
    

    With this approach after user re-loads the page all redux state will be lost, if you'd like to save that state you could choose a redux-persist library to sync the state to localStorage and use would probably use different caching strategy for redux-cached-api-middleware.

    0 讨论(0)
提交回复
热议问题