【问题标题】:Persistent local data on the clientside in MeteorMeteor 客户端的持久本地数据
【发布时间】:2016-12-30 12:20:43
【问题描述】:

我正在使用 Meteor + React。 问题是关于在客户端本地存储持久数据的正确方法

假设我有一个组件List,其中包含 5 篇文章:

export default class List extends Component {
  render() {
    return(
      <ul>
        <li><a href='/article1'>Article 1</li>
        <li><a href='/article2'>Article 2</li>
        <li><a href='/article3'>Article 3</li>
        <li><a href='/article4'>Article 4</li>
        <li><a href='/article5'>Article 5</li>
      </ul>
    );
  }
}

那么假设Article 组件应该为/articleN 之类的路由渲染。

export default class Article extends Component {
  render() {
    return(
      <main>
        ..
      </main>
    );
  }
}

我的目标是构建一个VisitedList 组件,其中包含已访问文章的列表。

我的解决方案使用 persistent-session 包 (link)。有几个像 persistent-minimongo 这样的包,但我需要一个 stable 解决方案。 u2622:persistent-session 超过 27k 的下载量让我觉得它相当稳定。但同样 - 我不确定。现在谈谈我的解决方案。

ComponentDidMount 部分的Article 组件中,我正在处理持久会话变量,例如数组元素。让我解释。首先,我检查是否存在带有key historyLengthSession 变量。如果不是(这意味着用户第一次访问文章页面),我设置了一个名为historyLength 的新持久变量,并且等于 0。我使用这个变量来存储我的历史自制“数组”的长度。

然后我检查当前文章是否在历史记录中,如果没有 - 我将其添加到历史记录。实际上添加到历史记录 - 使用key historyN 设置一个新的持久变量,其中N = historyLength

看代码更简单,而不是我试图用文字来解释它。

所以Article 组件的代码:

export default class Article extends Component {
  componentDidMount() {
          if (Session.get('historyLength')) {
              console.log('history exists');
          } else {
              Session.setPersistent('historyLength', 0);
              console.log('first history init');
          }

          var articleInHistory = false;

          for(i = 0; i < Session.get('historyLength'); i++) {
              var key = 'history' + i;
              if(Session.equals(key, this.props.articleName)) {
                  articleInHistory = true;
                  console.log('already in history:', i);
              } else {
                  console.log(i, 'product is not in history');
              }
          }
          if(!articleInHistory) {
              var newHistoryKey = 'history' + (Session.get('historyLength'));
              Session.setPersistent(newHistoryKey, this.props.articleName);

              var curHistoryLength = Session.get('historyLength');
              Session.setPersistent('historyLength', curHistoryLength + 1);
          }
  }
  render() {
    return(
      <main>
        ..
      </main>
    );
  }
}

此代码工作正常。我可以在任何组件中访问Session.get('historyLength'),然后使用for 循环获取访问文章的名称:

for(i = 0; i < Session.get(historyLength); i++) {
  let key = "history" + i;
  console.log(key, Session.get(key));
}

最后是VisitedList 组件:

export default class VisitedList extends Component {
  renderVisited() {
    var visitedArticles = [];
    for(i = 0; i < Session.get(historyLength); i++) {
      let key = "history" + i;
      visitedArticles.push(Session.get(key));
    }

    return visistedArticles.map((each) => {
      return <li> {each} </li>
    }
  }
  render() {
    return(
      <ul>
        { this.renderVisited() }
      </ul>
    );
  }
}

我的问题是:我的解决方案是存储和使用本地持久数据的正确方法吗? 这个例子很简单,不是来自真实的项目,但它显示了问题和问题的解决方案。

我将在我的项目和购物车中构建这样的历史块。因此,如果有更有效、更快速、更正确的方法来解决这个问题,那么在我开始之前我想知道它。感谢您的回答!

【问题讨论】:

    标签: session meteor reactjs local-storage persistent-storage


    【解决方案1】:

    Meteor Session 现在有些不鼓励使用(因为它污染了全局命名空间,因此很难跟踪其内容并保持其清洁等)。由于 u2622:persistent-session 与 Meteor 的 Session 对象一起使用,我认为这不是最适合未来的选择。由于您使用的是反应,您是否考虑过使用redux 进行客户端状态管理? Redux 正在迅速(如果还没有的话)成为 javascript/react 领域中最流行的应用程序状态容器。 Redux 本身不是持久性的,但是有几个附加库可以为您提供持久性功能,例如 redux-persist

    【讨论】:

    • 感谢您的回答!实际上我看到了有关 Redux 的提及,但对此一无所知。在普通的 react 应用中使用 redux 的原因很明显:组件只有状态,即一次性的。但是使用流星我们有不同的其他工具,比如 Session。我的时间真的很有限,所以重新开始使用新技术 (redux) 至少需要几天时间,而且正如我所见,redux 是构建应用程序的另一种不同方式,而我已经有了项目的工作版本。跨度>
    • 我想知道如何使用它的基本工具或小包在流星应用程序中实现历史块或购物车之类的东西。
    猜你喜欢
    • 1970-01-01
    • 2012-08-11
    • 2011-05-15
    • 1970-01-01
    • 2010-11-30
    • 2018-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多