Apollo + React:数据未出现在 componentDidMount 生命周期中
Posted
技术标签:
【中文标题】Apollo + React:数据未出现在 componentDidMount 生命周期中【英文标题】:Apollo + React: data not appearing in componentDidMount lifecycle 【发布时间】:2018-06-17 16:58:34 【问题描述】:我有一个 React 应用,它使用 Redux 进行一些应用内状态管理,并使用 Apollo 从服务器获取数据。在我的网络选项卡中,我的 graphql 查询成功并且响应是我所期望的,但是当我尝试在 React 组件的 componentDidMount 生命周期中引用数据时,数据不存在并且加载状态为“真”。
如果我将代码移动到不同的生命周期函数,例如 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】:首先不需要自己访问this.context
。这是一种反模式。始终使用connect()
。如果您需要组件中的部分状态,请使用mapStateToProps
。如果您想从您的组件中调度操作,请使用mapDispatchToProps
将函数传递给它,为您执行调度。这是connect()
接受的第二个参数。
此外,没有理由将 store 传递给子组件,因为您可以单独连接需要 store 中任何内容的每个组件。
话虽如此,您的问题是获取数据是异步的,并且在调用 componentDidMount()
时您的请求可能未完成。所以loading
是真的信息只是意味着你的获取还没有完成。您可以通过例如向用户显示它显示某种微调器,或者在渲染组件之前获取所需的数据。
【讨论】:
谢谢,好的建议,我会做出这些改变。我只是遵循 Boundless SDK 的作者提供的 redux 模式,但看起来那里有一些改进。是的,显然异步获取在 componentDidMount() 被调用时还没有完成,但是如果我把从渲染方法中的 for 循环的东西,我得到一个无限循环的结果。 把它放在render()
方法中不是解决方案。获取数据需要不确定的时间,具体取决于您无法始终影响的外部因素。您需要显示一些内容,表明您的组件仍在加载初始数据,只要它仍在获取。一旦数据到达,您的组件将使用数据重新渲染。或者您可以自己提供初始数据并将它们作为初始状态存储在您的 redux 存储中。
还使用react-apollo
阅读prefetching 数据。这可能就是你想要的。
感谢您尝试引导我完成此操作,但我仍然缺少一些东西。在 componentDidMount() 中,如果我使用 console.log(this.props.data.loading),我会得到“真”。尽管在那个生命周期方法中什么都不会再发生,那么我如何订阅才能知道它何时为“假”?
@bantingGamer 我对您的用例一无所知。在大多数情况下,您应该使用Query
component 来获取数据,如果您熟悉 React 钩子,则应使用 useQuery
。以上是关于Apollo + React:数据未出现在 componentDidMount 生命周期中的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 React 中的 Apollo 客户端中显示错误未显示
在 Apollo 客户端中使用 react-router 返回时 React 未更新其状态
React + Apollo:GraphQL 错误数组未传递到组件中
`data` 在 apollo useMutation Promise 中未定义