简体   繁体   English

反应-将状态传递给父组件-太多AXIOS请求

[英]React - Passing state to parent component - too many AXIOS requests

I'm a beginner both in programming and React and I have to create a functioning google Map single page website. 我是编程和React的初学者,我必须创建一个运行正常的Google Map单页网站。 I'm using google-map-react. 我正在使用google-map-react。
I have a parent App.js (containing the call to and a HTML sidebar) and a child Map.js containing the map itself and axios request function. 我有一个父App.js(包含对的调用和HTML边栏)和一个子Map.js,其中包含了地图本身和axios请求功能。 I'm making axios requests to fetch data from foursquare api. 我正在发出axios请求,以从foursquare api获取数据。 It works without side effects. 它没有副作用。 Then I want to pass those data to my app.js and update the parent state so that I can renderthe locations on the sidebar. 然后,我想将这些数据传递到我的app.js并更新父状态,以便可以在边栏上呈现位置。
This is the function I used (in Map.js). 这是我使用的功能(在Map.js中)。 I had to put the call in componentWillReceiveProps as a last resource because componentDidMount didn't work: 我不得不将调用作为最后的资源放入componentWillReceiveProps中,因为componentDidMount不起作用:

https://jsfiddle.net/kd1yuhe5/ https://jsfiddle.net/kd1yuhe5/

I think this may be the issue, but it's also the only way I found to make the list show: 我认为这可能是问题所在,但这也是我发现显示该列表的唯一方法:

this.props.updateVenues(this.state.venues)

This is the code from App.js 这是来自App.js的代码

    updateVenues(venues) {
    this.setState({
        venues: venues,
    });
}

Then I called the method like this: 然后我调用了这样的方法:

<Map updateVenues={this.updateVenues.bind(this)} />

The code works, venues are shown in the sidebar (if you need the code let me know, but I don't think it's relevant), but the I keep making requests until I exceed quota. 该代码有效,场地显示在侧边栏中(如果您需要该代码,请告诉我,但我认为这无关紧要),但是我会不断提出要求,直到超出配额为止。 Again: I'm a beginner. 再说一遍:我是一个初学者。 I just started 3 months ago. 我是3个月前刚开始的​​。

EDIT: Here are both components: 编辑:这两个组件:
Map.js Map.js
https://jsfiddle.net/kd1yuhe5/5/ https://jsfiddle.net/kd1yuhe5/5/

App.js App.js
https://jsfiddle.net/xwzrm4bp/2/ https://jsfiddle.net/xwzrm4bp/2/

When the state of a React component is updated (and without custom implementation of componentShouldUpdate), it triggers a re render of that component (ie call the render function). 当React组件的状态被更新(并且没有componentShouldUpdate的自定义实现)时,它会触发该组件的重新渲染(即调用render函数)。

If the props of the children of this component have changed since the last render, they will also re render. 如果自上次渲染以来此组件的子代的props已经更改,它们也将重新渲染。

They re render because they have received new props, and this will also call their componentWillReceiveProps function. 他们重新渲染是因为他们已经收到了新的道具,这也将调用其componentWillReceiveProps函数。

Since you are fetching data each time Map will receive props, you are fetching data each time something change (state change) on App. 由于您是在Map每次收到道具时都在获取数据,因此您每次在App上发生任何更改(状态更改)时都在获取数据。

First in Map.js, this.props.query is assigned to this.state.query . 首先在Map.js中,将this.props.query分配给this.state.query This looks like an error, as in this case what you want are the new props receceived by componentWillReceiveProps, this is the first argument of this function. 这看起来像一个错误,因为在这种情况下,您想要的是componentWillReceiveProps接收的新道具,这是此函数的第一个参数。 So you should assign props.query to this.state.query instead. 因此,您应该将props.query分配给this.state.query

Except that actually you should not: 除了实际上您不应:

this.state.query is only used in componentWillReceiveProps, therefore there is no need to put props.query into state.query. this.state.query仅在componentWillReceiveProps中使用,因此无需将props.query放入state.query。

Second since you have both this.props.query from the previous props update and props.query which is the new received query, you have the opportunity to fetch only when the query has actually changed: 其次,由于您同时具有以前的props更新中的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);
    }
}

Now you may ask, "ok but why my Map component was always re rendered, even when its props didn't changed". 现在,您可能会问:“好吧,为什么我的Map组件总是重新渲染,即使它的道具没有改变也是如此”。

But they did: in App.js 但是他们做到了:在App.js中

<Map 
    query={this.state.query}
    center={this.state.center}
    updateVenues={this.updateVenues.bind(this)}
    getClickedMarker={this.getClickedMarker.bind(this)}
/>

By calling this.updateVenues.bind(this) and this.getClickedMarker.bind(this) in the render method, you are creating new values (actually new Function references)for the updateVenues and getClickedMarker props, at each render. 通过调用this.updateVenues.bind(this)this.getClickedMarker.bind(this)的渲染方法,您正在创建的updateVenues和getClickedMarker道具新值(实际上是新功能的引用),在每个渲染。

Instead, you should bind these method in the contructor of App: 相反,您应该将这些方法绑定到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}
/>

This may limit your API calls a lot, you may also debounce them. 这可能会限制您的API调用很多,也可以将它们反跳

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM