反应本机订购中的渲染和构造函数console.log

时间:2017-10-14 15:56:04

标签: javascript react-native react-native-ios

我很难理解这个本机应用程序中的程序流程。

我已经在应用程序中输入了console.log语句,试图理解。

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

//来自渲染方法



[]
[]
[]




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



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




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

然而,在此之后,render方法继续print [],这对我来说似乎很奇怪,因为我只是在构造函数中设置它!

任何帮助将不胜感激。



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;
&#13;
&#13;
&#13;

如何覆盖构造函数中设置的变量?

由于

1 个答案:

答案 0 :(得分:2)

通常,React中的异步调用放在componentDidMount()生命周期方法中,该方法在初始调用render()后立即调用。 constructor用于初始化,即初始化组件state,在传入的任何super props组件方法上调用bind。我会将您的所有异步调用,包括对navigatorfetchAPI的调用移至componentDidMount,并确保您初始化的state不会导致{{1}上的任何错误}}。正如Tyler McGinnis在this post写的那样:

  

AJAX请求应该放在componentDidMount生命周期事件中。

     

这有几个原因,

     

Fiber,React的协调算法的下一个实现,将能够根据性能优势的需要启动和停止渲染。其中一个权衡因素是componentWillMount,它是制作AJAX请求可能有意义的另一个生命周期事件,将是“非确定性的”。这意味着React可能会在需要的时候开始在不同的时间调用componentWillMount。对于AJAX请求,这显然是一个糟糕的公式。

     

您无法保证在组件安装之前AJAX请求无法解析。如果确实如此,那就意味着你要在未安装的组件上尝试setState,这不仅不起作用,而且React会对你大喊大叫。在componentDidMount中执行AJAX将保证有一个要更新的组件。

以下是使用render并在所有异步请求解决后正确设置componentDidMount的完整重做示例。

state