Apollo + React:数据未出现在componentDidMount生命周期中

时间:2018-01-08 17:14:32

标签: reactjs apollo react-apollo

我有一个React应用程序,它使用Redux进行一些应用内状态管理,使用Apollo从服务器获取数据。在我的网络选项卡中,我的graphql查询成功并且响应是我所期望的,但是当我尝试在React Component的componentDidMount生命周期中引用数据时,数据不存在且加载状态为“true”。

如果我将代码移动到不同的生命周期函数(如render()),数据确实会出现,但我需要它在componentDidMount中工作。我是阿波罗的新手。

import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";

import SdkMap from "@boundlessgeo/sdk/components/map";
import SdkZoomControl from "@boundlessgeo/sdk/components/map/zoom-control";

import * as mapActions from "@boundlessgeo/sdk/actions/map";

import { graphql } from "react-apollo";
import gql from "graphql-tag";

function mapStateToProps(state) {
  return {
    map: state.map
  };
}

class Map extends Component {
  static contextTypes = {
    store: PropTypes.object.isRequired
  };

  componentDidMount() {
    const store = this.context.store;
    store.dispatch(mapActions.setView([-95.7129, 37.0902], 3));

    /* ADD SITES LAYER */
    store.dispatch(
      mapActions.addSource("sites_src", {
        type: "geojson",
        data: {
          type: "FeatureCollection",
          features: []
        }
      })
    );

    store.dispatch(
      mapActions.addLayer({
        id: "sites",
        source: "sites_src",
        type: "circle",
        paint: {
          "circle-radius": 3,
          "circle-color": "blue",
          "circle-stroke-color": "white"
        }
      })
    );
    
    console.log(this.props.data);  //response doesn't include query fields
    if (this.props.data.allSites) {
      let sites = this.props.data.allSites.edges;

      for (let i = 0; i < sites.length; i++) {
        let site = sites[i].node;
        let geojson = site.geojson;
        if (geojson) {
          console.log(site);
          const feature = {
            type: "Feature",
            geometry: geojson,
            properties: {
              id: site.id
            }
          };
          store.dispatch(mapActions.addFeatures("sites_src", feature));
        }
      }
    }
  }

  render() {
    const store = this.context.store;

    return (
      <SdkMap store={store} >
        <SdkZoomControl />
      </SdkMap>
    );
  }
}

const query = graphql(
  gql`
    query {
      allSites {
        edges {
          node {
            id
            projectId
            location
            areaAcres
            geojson
          }
        }
      }
    }
  `
);

const MapWithRedux = connect(mapStateToProps)(Map);
const MapWithApollo = query(MapWithRedux);

export default MapWithApollo;

1 个答案:

答案 0 :(得分:2)

首先,您无需亲自访问this.context。这是一种反模式。始终使用connect()。如果您在组件中需要部分状态,请使用mapStateToProps。如果要从组件中调度操作,请使用mapDispatchToProps将函数传递给它,以便为您执行调度。这是connect()接受的第二个参数。

此外,没有理由将商店传递给子组件,因为您可以单独连接每个需要商店的任何组件。

这就是说你的问题是获取数据是异步的,并且在调用componentDidMount()时你的请求可能没有完成。因此loading为真的信息仅表示您的提取尚未完成。您可以通过以下方式向用户显示该信息:显示某种微调器或在渲染组件之前获取所需的数据。