我对如何使它工作感到困惑。我有三个组件-ReportsWrapper,ReportsNearby和ReportSingle:
1.)ReportsWrapper获取设备位置数据,然后调用ReportsNear,并将位置作为道具传递
2.)ReportsNearby然后使用该位置填充mongodb中的“报告”集合
3.)“报告”中的每个记录都通过ReportSingle组件呈现
问题是“报告”集合在第一次加载时不会填充页面。页面加载后,客户端上未显示任何数据(来自mongodb的数据)。
如果我导航到其他页面(例如/ about或/ settings),然后返回ReportsWrapper,则该集合似乎已按预期填充,并且为每条记录显示一个ReportSingle。在ReportsWrapper上刷新后,该集合再次为空。
有任何想法吗?
ReportsWrapper.jsx
import React, {Component} from "react";
import TrackerReact from "meteor/ultimatejs:tracker-react";
import ReportsNearby from "./ReportsNearby.jsx";
export default class ReportsWrapper extends TrackerReact(Component) {
render() {
if (Geolocation.latLng() == null) {
return (
<span>Determining location...</span>
)
}
return (
<div>
<h1>Reports</h1>
<ReportsNearby latLng={Geolocation.latLng()} />
</div>
)
}
}
ReportsNearby.jsx
import React, {Component} from "react";
import TrackerReact from "meteor/ultimatejs:tracker-react";
import ReportSingle from "./ReportSingle.jsx";
import NearbyMap from "../maps/NearbyMap.jsx"
export default class ReportsNearby extends TrackerReact(Component) {
constructor(props) {
super(props);
this.state = {
subscription: {
reports: Meteor.subscribe("nearbyReports", 5, props.latLng)
}
}
}
componentWillUnmount() {
this.state.subscription.reports.stop();
}
_reports() {
return Reports.find().fetch();
}
render() {
console.log(this._reports()); // this is empty - why???
return (
<div>
<ul>
{this._reports().map((report, index)=> {
return <ReportSingle key={report._id}
report={report}
})}
</ul>
</div>
)
}
}
ReportSingle.jsx
import React, {Component} from 'react';
export default class ReportSingle extends Component {
render() {
return (
<li>
<a href={`/report/${this.props.report._id}`}>
{this.props.report.category}<br/>
{this.props.report.description}<br/>
{this.props.report.status}
</a>
</li>
)
}
}
routes.jsx
import React from "react";
import {mount} from "react-mounter";
import {MainLayout} from "./layouts/MainLayout.jsx";
import ReportsWrapper from "./reports/ReportsWrapper.jsx";
import Settings from "./Settings.jsx";
import About from "./About.jsx";
FlowRouter.route('/', {
action() {
mount(MainLayout, {
content: <ReportsWrapper />
})
}
});
FlowRouter.route('/settings', {
action() {
mount(MainLayout, {
content: <Settings />
})
}
});
FlowRouter.route('/about', {
action() {
mount(MainLayout, {
content: <About />
})
}
});
publish.jsx
Meteor.publish("nearbyReports", function (limit, latLng) {
Reports._ensureIndex({'lngLat': '2dsphere'});
return Reports.find({
lngLat: {
$near: {
$geometry: {
type: "Point",
coordinates: [latLng.lng, latLng.lat]
},
$minDistance: 0,
$maxDistance: 3218.69 // this is 2 miles in meters
}
}
}, {
sort: {createdAt: -1},
limit: limit,
skip: 0
});
});
最佳答案
我最终通过将以下代码添加到ReportsWrapper.jsx来使此工作正常进行。我认为ReportsNearby并未按预期获得latLng道具,即使我已将控制台记录下来以进行验证。
tl; dr使用计时器间隔来确保您的应用已收到该位置。
constructor () {
super();
this.state = {
handle: null,
latLng: Geolocation.latLng()
}
}
componentDidMount() {
if (this.state.latLng != null) {
return
}
// Attempt to reload the location if it was not found. do this because the device
// location is not immediately available on app start
this.state.handle = Meteor.setInterval(()=> {
if (Geolocation.latLng() != null) {
this.setState({latLng: Geolocation.latLng()}); // Setting the state will trigger a re-render
Meteor.clearInterval(this.state.handle); // Stop the interval function
}
}, 500)
}
componentWillUnmount() {
// Make sure interval is stopped
Meteor.clearInterval(this.state.handle);
}