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

只谈情不闲聊 提交于 2021-02-17 19:14:42

问题


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 population of dropdowns as well. But I am not sure how this can be achieved. I am currently making a new request whenever the drop-down value is selected. Please do suggest me how to do implement it efficiently without making multiple unwanted rest calls.


回答1:


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




回答2:


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.




回答3:


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?



来源:https://stackoverflow.com/questions/46842500/how-to-cache-api-response-and-use-it-later-in-react-redux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!