javascript - 反应 - 将状态传递给父组件 - 过多的 AXIOS 请求
问题描述
我是编程和 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/
解决方案
当 React 组件的状态被更新(并且没有 componentShouldUpdate 的自定义实现)时,它会触发该组件的重新渲染(即调用渲染函数)。
如果该组件的子组件的 props 自上次渲染后发生了变化,它们也会重新渲染。
他们重新渲染是因为他们收到了新的道具,这也会调用他们的 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。
其次,由于您同时拥有来自先前 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);
}
}
现在你可能会问,“好吧,但为什么我的 Map 组件总是被重新渲染,即使它的 props 没有改变”。
但他们做到了:在 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 道具创建新值(实际上是新的函数引用)。
相反,您应该在 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 调用,您也可以对它们进行去抖动。
推荐阅读
- python - UE4 在 Python 中按父类类型过滤 AssetData
- c++ - QT VS Tools 无法打开 .pro 项目
- java - ValueAnimator 似乎无法在我的手机上正常工作
- spring - 春季批处理 - 在从数据库读取下一页之前未完全处理数据
- swift - 如何快速调用 Firebase
- javascript - 选择中的禁用属性不起作用(Angular)
- django - django s3direct 文件上传通过管理面板工作,但不通过模型表单
- migration - 使用内容矩阵工具将 SharePoint 2013 迁移到在线 SharePoint
- javascript - webpack splitchunks 导入块
- javascript - 使用 react native expo 将文件上传到 firebase 存储