如何在React中缓存获取的数据而不使用Redux

26
我知道使用 Redux 会有一个共享的 store ,当我改变我的位置,例如我从 /videos 页面离开,但是我仍然在我的 videos reducer 中拥有已经获取的视频。所以如果我决定回到我的 videos 页面,我将从我的存储中展示用户已经加载的视频,并且如果他需要并储存它们,还可以加载更多。
但是在 React 中没有 Redux ,如果我改变了我的位置 /videos,我先前通过网络获取的视频就不存在于我的本地状态中的 VideosPage 组件中了。当我重新回到这个页面时,我必须重新从头开始获取它们。
如何对它们进行缓存并能否实现此操作?
附言:这是更多的理论性问题,没有提供代码。
5个回答

16

当您想在以后的某个时间点重新填充数据时,最好的保存数据的方式是将其保存在localStorage中,这样即使刷新应用程序,您也可以获取数据。

const InitialState = {
   someState: 'a'
}
class App extends Component {

 constructor(props) {
  super(props);

  // Retrieve the last state
  this.state = localStorage.getItem("appState") ? JSON.parse(localStorage.getItem("appState")) : InitialState;

}

componentWillUnmount() {
  // Remember state for the next mount
  localStorage.setItem('appState', JSON.stringify(this.state));
}

render() {
  ...
 }
}

export default App;

3
什么?这个回答太糟糕了。OP正在询问如何在SPA的不同页面之间保留数据。在导航期间,js内存不会被清除。你可以将状态存储在内存中!将其放入localStorage是不必要的复杂。你可以使用window.myVar或者像这样使用import:https://dev59.com/questions/5lsX5IYBdhLWcg3wALba#55624363 - John Henckel

6
虽然目前被广泛接受的解决方案(将状态存储在localStorage中)可以完成任务,但我不建议采用此方式,因为它会破坏很多模式。这样你就部分地将状态管理移到React生态系统之外,违反了状态机模式,并使你的应用程序依赖于外部全局变量。只要它只是一种缓存且只在此位置进行访问和设置,那么这并不是最糟糕的行为,但你永远不知道何时会有一个开发人员过来想“哦,嘿,我有这个状态存在localStorage中,我只需那样获取它”,那你就会遇到麻烦。
相反,我建议采用以下方法之一:
1. 将状态存储在未卸载的父组件中,并通过props向相关组件提供数据和状态设置器的访问权限。
2. 为状态设置上下文提供程序,在那里存储它,然后使用useState hook或上下文消费者订阅需要使用它的上下文。
每种方法都有一些缺点。例如,第一种选择需要进行更多的prop drilling,而且你将在一个与状态无直接关系的抽象层级上存储状态。而在后一种情况下,如果你只在一个地方或一个组件层面上使用状态,则使用上下文可能会有些重量级。但我将让你自己判断哪种方法对你的用例更简单。
不管哪种方法,都可以将你的全部状态管理保留在React生态系统内,并避免你或未来的开发人员违反现有理念。

5

您可以使用以下方式进行缓存:

1)本地存储

2)Redux存储

3)在挂载和卸载之间保留数据

import React, { Component, PropTypes } from 'react';

// Set initial state
let state = { counter: 5 };

class Counter extends Component {

 constructor(props) {
  super(props);

  // Retrieve the last state
  this.state = state;

  this.onClick = this.onClick.bind(this);
}

componentWillUnmount() {
  // Remember state for the next mount
  state = this.state;
}

onClick(e) {
  e.preventDefault();
  this.setState(prev => ({ counter: prev.counter + 1 }));
}

render() {
  return (
    <div>
      <span>{ this.state.counter }</span>
      <button onClick={this.onClick}>Increase</button>
    </div>
  );
 }
}

export default Counter;

1
您的问题在于当您导航时组件会卸载。
您可以将视频状态提升到不会卸载的组件中。
或者,如果您避免使用redux并且取决于如何处理导航,则始终可以挂载您的视频容器,如果路由匹配,则呈现videos,否则返回null

0
如果您想在浏览器级别(客户端)保存数据(复杂数据类型),可以使用现在在大多数现代浏览器中兼容的IndexDb。 IndexDB提供了事务和索引功能,以在浏览器级别保存和获取数据。而且是异步的。 请点击以下链接获取有关浏览器缓存的更多详细信息。 IndexedDB and Caching

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接