首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同一页上单一存储的多种用途

同一页上单一存储的多种用途
EN

Stack Overflow用户
提问于 2017-10-30 07:23:23
回答 1查看 77关注 0票数 0

我有一个执行fetch的存储,它使用mobx-utils的asyncAction从我的服务器获取图形数据。

看起来是这样的:

代码语言:javascript
复制
class GraphStore {
    @observable
    public loading: boolean;
    @observable
    public datapoints: any[];

    @asyncAction
    *fetch(id: string) {
         const datapoints = yield fetch('/api/datapoints');
         this.loading = false;
         this.datapoints = datapoints;
    }
}

在我的组件中,我使用它的方式如下:

代码语言:javascript
复制
@inject(STORE_GRAPH)
class Graph {
componentWillMount() {
    const graphStore= this.props[STORE_GRAPH] as GraphStore;
    const { id }  = this.props;

    graphStore.fetch(id);
}
render(){
    const graphStore= this.props[STORE_GRAPH] as GraphStore;
    if(graphStore.loading)
        return <h2>Loading</h2>

    return (
       <Chart datapoints={graphStore.datapoints}/>
    );
}

这很好用,但是当我想把它扩展到在同一个页面上显示2个图形时,我不知道该怎么做?基本上,我希望有一个类似于这样的父组件:

代码语言:javascript
复制
render() {
    return (
        <Graph id="foo"/>
        <Graph id="bar"/>
    );
}

基于这段代码,相同的图形存储被注入到两个组件中,导致两个取出,而两个图都以相同的数据点结束--不管最后一个是哪一个。

做这件事的正确方法是什么?我是不是想错了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-31 04:47:13

有很多方法可以做到这一点,但我会利用MobX的面向对象特性,创建一个数据存储,该存储被实例化并作为所有组件的提供程序传递。如果你愿意的话,你可以把它看作是你的“本地数据库”。

然后,只需在该数据存储上添加方法,以获取和创建不同的图形实例。

下面是一些示例代码(没有类型记录)

代码语言:javascript
复制
// stores/data.js

import Graph from './Graph';

class DataStore {

  @observable graphs = observable.map();

  @action getGraphById(id) {
    if (!this.graphs.has(id)) {
      this.graphs.set(id, new Graph(id))
    }
    return this.graphs.get(id);
  }

}

export default new DataStore();

然后创建一个可实例化的图形对象

代码语言:javascript
复制
// stores/Graph.js

export default class Graph {
  @observable id;
  @observable loading = false;
  @observable datapoints = [];

  constructor(id) {
    this.id = id;
    if (!this.hasData) {
      this.fetch();
    }
  }

  @computed get hasData() {
    return this.datapoints.length;
  }

  @action async fetch() {
    this.loading = true;
    const datapoints = await fetch(`/api/datapoints/${this.id}`);
    this.loading = false;
    this.datapoints = datapoints;
  }
}

在组件树中,您将通过提供程序传递dataStore

代码语言:javascript
复制
import dataStore from './stores/data'

<Provider stores={{ data: dataStore }}>
  <Graph id="foo" />
  <Graph id="bar" />
</Provider>

然后,只需使用组件中的id支柱来启动提取。

代码语言:javascript
复制
@inject('data')
@observer
class Graph extends Component {

  @observable graph;

  componentWillMount() {
      const { id, data }  = this.props;
      this.graph = data.getGraphById(id);
  }

  render() {
    if (this.graph.loading) {
      return <h2>Loading</h2>
    }
    return (
       <Chart datapoints={this.graph.datapoints} />
    );
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47009922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档