Reactjs React(带React redux)缓存选项
我正在构建一个应用程序,用户可以在其中登录并查看大量统计数据 每个stat都是一个API调用的结果——想象一下一个有几列的表,每列包含一个stat(只是一个数字) 我注意到,每次重新呈现组件时,都会再次进行API调用。这会带来严重的性能问题,因为stat可能需要几毫秒的时间才能显示。我如何: a) 缓存此信息,使其保持不变,并且无需在每次渲染时重新调用, b) 让应用程序“知道”何时重新调用API,因为数据库中的状态已更新 我目前正在使用Redux来存储更明显的东西,比如用户正在查看的活动,但肯定有更好的方法来缓存这些统计数据,而不是为每个统计数据创建操作和还原程序?a)要将数据缓存到本地存储,请观看Dan Abramov的这篇文章(《Redux》作者) b) 为避免重新提交组件,请使用shouldComponentUpdateReactjs React(带React redux)缓存选项,reactjs,caching,redux,react-redux,Reactjs,Caching,Redux,React Redux,我正在构建一个应用程序,用户可以在其中登录并查看大量统计数据 每个stat都是一个API调用的结果——想象一下一个有几列的表,每列包含一个stat(只是一个数字) 我注意到,每次重新呈现组件时,都会再次进行API调用。这会带来严重的性能问题,因为stat可能需要几毫秒的时间才能显示。我如何: a) 缓存此信息,使其保持不变,并且无需在每次渲染时重新调用, b) 让应用程序“知道”何时重新调用API,因为数据库中的状态已更新 我目前正在使用Redux来存储更明显的东西,比如用户正在查看的活动,但肯
shouldComponentUpdate(nextProps, nextState) {
/**If no change in state return false*/
return this.state.value != nextState.value;
}
通过这种方式,您可以停止不必要的重新招标。因为我正在使用Redux,所以答案并不像我希望的那么简单。根据上面的答案,我算出了答案 首先,当组件挂载时,它执行一个API调用,该调用依次触发一个操作,然后是reducer,reducer随后更新存储 其次,我使用的
shouldComponentUpdate
如下:
shouldComponentUpdate(nextProps){
if(nextProps.value){
return true
}
if(this.props.value){
return false;
}
return true;
}
如果组件具有nextProps,请重新渲染。如果它已经有一个值,不要重新渲染,如果它没有(有道具)渲染
我仍然在使用
componentDidMount()
调用API,该API在每次使用组件时都会有效地侦听,而呈现(或不呈现)的决定是由shouldComponentUpdate()方法做出的。本质上,您需要在redux reducer中处理每个获取操作。这就是为什么(在实现了几次缓存之后)我决定发布一个库(),它是专门为在这种情况下提供帮助而设计的(它是一个薄包装)。您只需要为每个请求考虑唯一的缓存密钥
下面是一个示例组件,它从API获取项目,并使用10分钟缓存策略(这意味着如果您尝试在缓存有效时调用API,它将仅从缓存返回数据):
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import api from 'redux-cached-api-middleware';
import Items from './Items';
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 <Items data={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.CACHE_TYPES.TTL_SUCCESS)
.buildStrategy({ ttl: 10 * 60 * 1000 }), // 10 minutes
},
})
);
},
})
);
export default enhance(ExampleApp);
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)
);