我有一个Node API,它以JSON格式返回数据并将其发送到React Component App
,后者将其存储在其状态(nearbyShops
)中,然后将其传递给{{1}组件道具。问题是即使我使用了NearbyShop
,我也没有显示内容。
componentDidMount
:
App.js
import React, { Component } from 'react';
import axios from 'axios';
import './App.css';
import NearbyShop from './NearbyShop';
class App extends Component {
constructor(props) {
super(props);
this.state = {
lat: 0,
long: 0,
nearbyShops: []
}
}
componentDidMount() {
var that = this;
// Get the user's location (lat & long) in the state object
const url = 'https://freegeoip.net/json/';
axios.get(url)
.then((response) => response.data)
// Get the long & lat of the end-user
.then((data) => that.setState({
lat: data.latitude,
long: data.longitude
}))
// Call our built-in Nearby API with the lat & long of the end-user
.then(function (data) {
axios.get('/nearby', {
params: {
lat: that.state.lat,
long: that.state.long
}
})
.then((response) => that.setState({
nearbyShops: response.data.nearbyShops
}))
.catch(function (error) {
console.log(error);
});
})
.catch(function (error) {
console.log(error);
});
}
render() {
return (
<div className="App">
<h1>Shops List</h1>
<NearbyShop shopsList={this.state.nearbyShops} />
</div>
);
}
}
export default App;
:
NearbyShop.js
答案 0 :(得分:1)
NearbyShop
组件是混合状态和道具。
NearbyShop
不需要管理state
,因为数据是通过props
从父组件传递的。当父提供的props
更改API请求时,它将重新呈现。
当前代码集是组件初始化时的state
,它永远不会在组件未初始化时再次更新,也不会再次mounted进行更新。所以只有初始状态,空数组[]
才是渲染的全部。
class NearbyShop extends React.Component {
render() {
const { shopsList } = this.props
if (!shopsList || shopsList.length == 0)
return null;
const shops = shopsList.map(function (shop, i) {
<Card key={i}>
<CardImg top width="100%" src={shop.picture} alt="Card image cap" />
<CardBody>
<CardTitle>{shop.name}</CardTitle>
<CardSubtitle>Card subtitle</CardSubtitle>
<CardText>{shop.email}</CardText>
<Button>Fall in love</Button>
</CardBody>
</Card>
})
return (
<CardGroup>
{shops}
</CardGroup>
);
}
}
此外,正如Kryten所说,App
API请求混合了承诺和setState
回调。此可能导致您的API请求与您的状态更新失去同步,并最终导致呈现的结果不一致。状态更改可以在最后一起批处理以进行单个更新/呈现。
componentDidMount() {
// Get the user's location (lat & long) in the state object
const url = 'https://freegeoip.net/json/';
const state_updates = {}
axios.get(url)
.then((response) => {
const data = response.data
// Get the long & lat of the end-user
state_updates.lat = data.latitude
state_updates.long = data.longitude
return axios.get('/nearby', {
params: {
lat: state_updates.lat,
long: state_updates.long
}
})
})
.then((response) => {
state_updates.nearbyShops = response.data.nearbyShops
this.setState(state_updates)
return true
})
.catch(function (error) {
console.log(error);
})
}
此代码仍然没有等待setState
完成,但现在它正在完成最后一项工作,并且承诺流不依赖于组件中的异步更改{{1不再。
答案 1 :(得分:-1)
问题可能源于setState
未返回承诺的事实 - 如果您希望在更新后使用更新状态值,则需要回调。
因此,当您尝试到达附近的地点时,您可能会失败:
axios.get(url)
.then((response) => response.data)
// Get the long & lat of the end-user
.then((data) => that.setState({
lat: data.latitude,
long: data.longitude
}))
// Call our built-in Nearby API with the lat & long of the end-user
.then(function (data) {
// data is undefined here, since it was returned from
// setState. In addition, there is no guarantee that
// the state has been updated and your lat & long values
// are probably not accurate
axios.get('/nearby', {
params: {
lat: that.state.lat,
long: that.state.long
}
})
})
将setState()视为请求而不是更新组件的立即命令。为了获得更好的感知性能,React可能会延迟它,然后在一次通过中更新几个组件。 React不保证立即应用状态更改。