react本机排序console.log中的Render和Constructor



我在理解这个react原生应用程序中的程序流时遇到了一些困难。

我已经把console.log语句放到了应用程序中,试图理解。

因此,我将构造函数中的状态初始化为lat:0、long:0、err:null和marks:[]。然后在构造函数中,我调用API方法来获取所有位置并填充标记方法。打印输出如下:

//从渲染方法

[]
[]
[]

//然后构造函数async方法返回,我们设置标记

{markers: [{title: "A", coordinate: {latitude: 0, longitude: 1}, description: "abc"},
{title: "B", coordinate: {latitude: 0, longitude: 1}, description: "abc"}]}

然后我调用render方法,我知道这可能是一种糟糕的做法,但它只是尝试调试,希望标记在地图上可见。

然而,在这之后,render方法继续打印[],这对我来说真的很奇怪,因为我刚刚在构造函数中设置了它!

如有任何帮助,我们将不胜感激。

import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View
} from 'react-native';
import MapView from 'react-native-maps';
const styles = StyleSheet.create({
container: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'flex-end',
alignItems: 'center',
},
map: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
},
});
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload,n' +
'Shake or press menu button for dev menu',
});
class App extends Component {
constructor(props) {
super(props);
this.state = {
latitude: 0,
longitude: 0,
error: null,
markers: []
};
navigator.geolocation.getCurrentPosition(
(position) => {
this.state = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
};
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
fetch(API_URL)
.then((response) => response.json())
.then((responseJson) => {
var relevantLocations = []
for (var i = 0; i < responseJson.length; i++) {
var location = responseJson[i];
relevantLocations.push({
title: location.name,
coordinate: {latitude: location.latitude, longitude: location.longitude},
description: "test" + i
});
}
console.log("Setting state");
this.state = {
markers: relevantLocations
};
console.log(this.state);
this.render();
})
.catch((error) => {
console.error(error);
});
}
onRegionChange = (region) => {
this.setState({ region });
}
onPress = () => {
}
render() {
console.log(this.state.markers);
return (
<View style={styles.container}>
<MapView style={styles.map}
onRegionChange={this.onRegionChange}
onPress={this.onPress}
>
{this.state.markers.map(marker => {
return <MapView.Marker
key={marker}
coordinate={marker.coordinate}
title={marker.title}
description={marker.description}
/>
})}
</MapView>
</View>
);
}
}
export default App;

我在构造函数中设置的变量是如何被覆盖的?

感谢

React中的异步调用通常放置在componentDidMount()生命周期方法中,该方法在对render()的初始调用之后立即调用。constructor用于初始化,即初始化组件state,对传入的任何props调用superbind调用组件方法。我会将您的所有异步调用,包括对navigatorfetchAPI的调用,移动到componentDidMount中,并确保您初始化的任何state都不会在render上导致任何错误。正如Tyler McGinnis在这篇文章中所写:

AJAX请求应该进入componentDidMount生命周期事件。

这有几个原因,

作为React协调算法的下一个实现,Fiber将能够根据需要启动和停止渲染,以提高性能。其中一个权衡是componentWillMount,另一个可能有意义发出AJAX请求的生命周期事件,将是"不确定的"。这意味着React可能会在需要的时候随时调用componentWillMount。对于AJAX请求来说,这显然是一个糟糕的公式。

您不能保证AJAX请求不会在组件装载之前得到解决。如果是这样,那就意味着你将试图在一个未安装的组件上设置State,这不仅不起作用,而且React会为此对你大喊大叫。在componentDidMount中执行AJAX将保证有一个组件需要更新。

这是一个完整的重新设计的示例,使用componentDidMount并在所有异步请求都得到解决后正确设置state

import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View
} from 'react-native';
import MapView from 'react-native-maps';
const styles = StyleSheet.create({
container: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'flex-end',
alignItems: 'center',
},
map: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
},
});
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload,n' +
'Shake or press menu button for dev menu',
});
class App extends Component {
constructor(props) {
super(props);
this.state = {
latitude: 0,
longitude: 0,
error: null,
markers: []
};
}
componentDidMount() {

navigator.geolocation.getCurrentPosition(
(position) => {

fetch(API_URL)
.then((response) => response.json())
.then((responseJson) => {
var relevantLocations = []
for (var i = 0; i < responseJson.length; i++) {
var location = responseJson[i];
relevantLocations.push({
title: location.name,
coordinate: {latitude: location.latitude, longitude: 
location.longitude},
description: "test" + i
});
}
console.log("Setting state");
this.setState({
...this.state
latitude: position.coords.latitude,
longitude: position.coords.longitude,
markers: relevantLocations
});
})
.catch((error) => {
console.error(error);
});
},
(error) => this.setState({ ...this.state, error: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);

}
onRegionChange = (region) => {
this.setState({ region });
}
onPress = () => {
}
render() {
console.log(this.state.markers);
return (
<View style={styles.container}>
<MapView style={styles.map}
onRegionChange={this.onRegionChange}
onPress={this.onPress}
>
{this.state.markers.map(marker => {
return <MapView.Marker
key={marker}
coordinate={marker.coordinate}
title={marker.title}
description={marker.description}
/>
})}
</MapView>
</View>
);
}
}
export default App;

相关内容

  • 没有找到相关文章

最新更新