如何在 Redux 中实现缓存?

编程入门 行业动态 更新时间:2024-10-09 20:25:52
本文介绍了如何在 Redux 中实现缓存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

如果我的商店中已有数据,我希望避免调用 API 两次.

I would like to avoid calling an API twice if I already have the data in my store.

我如何使用 Redux 做到这一点?

How do I do this with Redux?

推荐答案

在我看来,理想的解决方案是使用 Reselect 选择器 (github/reactjs/reselect).这是一个人为的例子:

The ideal solution to this in my opinion is to use Reselect selectors (github/reactjs/reselect). Here is a contrived example:

import { createSelector } from 'reselect'; const getObjs = state => state.objs; const currentObjId = state => state.currentObjId; export const getObj = createSelector( [ currentObjId, getObjs ], (id, objs) => objs.get(href) );

这样使用:

import { getObj } from './selectors'; const ExampleComponent = ({obj}) => <div>{ obj.name }</div>; const mapStateToProps = state => ({ obj: getObj(state) }); export default connect(mapStateToProps)(ExampleComponent);

第一次运行时,一个基于某些id(也在状态中)的obj将从所有objs的列表中选择".下一次,如果输入没有改变(查看等价定义的重新选择文档),它将简单地返回上次的计算值.

The first time you run this, one obj based on some id (also in the state) will be "selected" from the list of all objs. The next time, if the inputs have not changed (look at reselect documentation for the definition of equivalence) it will simply return the computed value from last time.

您还可以选择插入不同类型的缓存,例如LRU.这有点高级,但非常可行.

You also have the option to plug-in a different type of cache, e.g. LRU. That's a bit more advanced, but very doable.

Reselect 的主要优点是它允许您进行干净的优化,而无需在 redux 中手动维护额外的状态,如果对原始数据进行了更改,您将不得不记住更新.Timo 的回答很好,但我认为它的弱点在于它不缓存昂贵的客户端计算(我知道这不是确切的问题,但这个答案是关于一般最佳实践 redux 缓存,适用于您的问题),只取.您可以执行与 Timo 建议的非常相似的操作,但合并 reselect 以获得非常整洁的解决方案.在动作创建者中,您可能有这样的事情:

The major advantage of Reselect is that it allows you to cleanly optimise without manually maintaining extra state in redux that you would then have to remember to update if a change to the original data was made. Timo's answer is good, but I would argue that the weakness is that it doesn't cache expensive client side computation (I know this wasn't the exact question, but this answer is about best practice redux caching in general, applied to your problem), only fetching. You can do something very similar to what Timo suggests, but incorporate reselect for a very tidy solution. In an action creator you could have something like this:

export const fetchObj = (dispatch, getState) => { if (hasObj(getState())) { return Promise.resolve(); } return fetchSomething() .then(data => { dispatch(receiveObj(data)); return data; }); };

您将有一个专门用于 hasObj 的选择器,可能基于上述选择器(我在这里这样做是为了展示如何轻松组合选择器),例如:

You would have a selector specifically for hasObj potentially based on the above selector (I do so here specifically to show how you can compose selectors easily), like:

export const hasObj = createSelector( [ getObj ], obj => !!obj );

一旦您开始使用它与 redux 进行交互,即使对于简单的选择,在 mapStateToProps 中专门使用它也开始变得有意义,以便在将来,如果计算状态的方式发生变化,您无需修改​​所有使用该状态的组件.这方面的一个例子可能是当用于在几个不同的组件中呈现列表时拥有一个 TODO 数组.稍后在您的应用程序开发过程中,您意识到您希望默认情况下仅过滤不完整的 TODO 列表.您只需在一处更改选择器即可.

Once you start using this to interface with redux, it starts to make sense to use it exclusively in mapStateToProps even for simple selects so that at a future time, if the way that state is computed changes, you do not need to modify all of the components which use that state. An example of this might be something like having an array of TODOs when is used to render a list in several different components. Later in your application development process you realise you want to filter that list of TODOs by default to only ones that are incomplete. You change the selector in one place and you are done.

更多推荐

如何在 Redux 中实现缓存?

本文发布于:2023-11-30 21:49:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1651576.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:缓存   如何在   Redux

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!