react-native ordering console.log 中的渲染和构造函数

游泳G

我在理解这个 React Native 应用程序中的程序流程时有点困难。

我已经在应用程序中放置了 console.log 语句,以尝试理解。

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

//来自render方法

[]
[]
[]

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

{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,调用super任何props传入,bind荷兰国际集团组件的方法。我将所有的异步调用,包括调用navigatorfetchAPIcomponentDidMount,并确保无论state您初始化不会造成任何错误的render正如 Tyler McGinnis 在这篇文章中所写

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

这有几个原因,

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

您不能保证在组件安装之前 AJAX 请求不会解决。如果是这样,那将意味着您将尝试在未挂载的组件上设置状态,这不仅不起作用,而且 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;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使console.log在React Native中为Android工作

来自分类Dev

从React Native应用中删除console.log

来自分类Dev

React-Native:无法输出到 console.log()?

来自分类Dev

React,console.log和渲染显示不同的值

来自分类Dev

为什么React Component构造函数中的console.log(super)抛出错误?

来自分类Dev

console.log 在 react 和 graphql 中不起作用

来自分类Dev

React Native 在渲染方法中调用函数

来自分类Dev

使用中的React,React Hooks,Diffrent console.log打印顺序

来自分类Dev

React 不渲染 props 但可以在 console.log 中看到

来自分类Dev

React-native,构造函数和componentWillReceiveProps之间的区别

来自分类Dev

在React Native中渲染HTML

来自分类Dev

React Native中的条件渲染

来自分类Dev

在 React-Native 中渲染

来自分类Dev

React Native FlatList - 在返回组件的渲染方法中调用函数

来自分类Dev

函数中的JavaScript console.log

来自分类Dev

在JavaScript console.log中

来自分类Dev

为什么console.log在react js中记录两次?

来自分类Dev

为什么console.log(“ hello)在React钩子中打印六次

来自分类Dev

console.log在React中检查复选框值的数组

来自分类Dev

React Native交错渲染

来自分类Dev

在React和React Native中的组件之间传递函数

来自分类Dev

构造函数和渲染方法在react组件中运行两次

来自分类Dev

React Native 中的循环函数

来自分类Dev

查看console.log的lambda函数

来自分类Dev

复制/覆盖javascript的console.log函数

来自分类Dev

复制/覆盖javascript的console.log函数

来自分类Dev

查看console.log的lambda函数

来自分类Dev

如何在React Native中渲染对象?

来自分类Dev

在我的渲染React Native中显示变量

Related 相关文章

热门标签

归档