我是编程和React的初学者,我必须创建一个运行正常的Google Map单页网站。我正在使用google-map-react。
我有一个父App.js(包含对的调用和HTML边栏)和一个子Map.js,其中包含了地图本身和axios请求功能。
我正在发出axios请求,以从foursquare api获取数据。它没有副作用。然后,我想将这些数据传递到我的app.js并更新父状态,以便可以在侧栏上呈现位置。
这是我使用的功能(在Map.js中)。我不得不将调用作为最后一个资源放在componentWillReceiveProps中,因为componentDidMount不起作用:
https://jsfiddle.net/kd1yuhe5/
我认为这可能是问题所在,但这也是我发现显示列表的唯一方法:
this.props.updateVenues(this.state.venues)
这是App.js中的代码
updateVenues(venues) {
this.setState({
venues: venues,
});
}
然后我这样调用方法:
<Map updateVenues={this.updateVenues.bind(this)} />
该代码有效,场地显示在侧边栏中(如果您需要该代码,请告诉我,但我认为这无关紧要),但是我会不断提出请求,直到超出配额为止。 再说一遍:我是一个初学者。我刚开始3个月前。
编辑:
这是两个组件:
Map.js
https://jsfiddle.net/kd1yuhe5/5/
答案 0 :(得分:0)
当React组件的状态被更新(并且没有componentShouldUpdate的自定义实现)时,它会触发该组件的重新渲染(即调用render函数)。
如果此组件的子代的道具自上次渲染以来已更改,则它们也会重新渲染。
他们重新渲染是因为他们收到了新的道具,这也将调用其componentWillReceiveProps函数。
由于每次Map都会收到道具时都在获取数据,因此每次App发生任何更改(状态更改)时都在获取数据。
首先在Map.js中,将this.props.query
分配给this.state.query
。
这看起来像一个错误,因为在这种情况下,您想要的是componentWillReceiveProps接收的新道具,这是此函数的第一个参数。
因此,您应该将props.query
分配给this.state.query
。
除了实际上您不应:
this.state.query仅用于componentWillReceiveProps,因此无需将props.query放入state.query。
第二个原因是您同时拥有来自先前道具更新的this.props.query和作为新接收到的查询的props.query,因此您只有在查询实际更改时才有机会获取:
// Receive the update query from parent and fetch the data
componentWillReceiveProps(nextProps){
if (this.props.query !== nextProps.query) {
this.fetchData(nextProps.query);
}
}
现在您可能会问,“好吧,为什么我的Map组件总是重新渲染,即使其道具没有改变也是如此。”
但是他们做到了: 在App.js中
<Map
query={this.state.query}
center={this.state.center}
updateVenues={this.updateVenues.bind(this)}
getClickedMarker={this.getClickedMarker.bind(this)}
/>
通过在render方法中调用this.updateVenues.bind(this)
和this.getClickedMarker.bind(this)
,您将在每个渲染中为updateVenues和getClickedMarker道具创建新值(实际上是新的Function引用)。
相反,您应该将这些方法绑定到App的构造器中:
constructor(props) {
super(props);
this.updateVenues = this.updateVenues.bind(this);
this.getClickedMarker = this.getClickedMarker.bind(this);
....
}
....
<Map
query={this.state.query}
center={this.state.center}
updateVenues={this.updateVenues}
getClickedMarker={this.getClickedMarker}
/>
这可能会限制您的API调用,也可以debounce它们。