Действительно быстрый вопрос о том, как ссылаться на переменные состояния в render() — React Native

#javascript #reactjs #react-native #maps #expo

#javascript #reactjs #react-native #Карты #выставка

Вопрос:

Я думал, что это простая проблема с синтаксисом, но, возможно, это более широкая концепция, которую я не понимаю в отношении иерархии и наследования.

Я создаю приложение в react native (expo). Я хочу отобразить карту, ориентированную на пользователя, которая постоянно обновляется (в конечном итоге я буду использовать watchCurrentPositionAsync, но поскольку я новичок, я хочу просто попробовать собрать информацию о местоположении один раз, а затем выяснить это оттуда). Приведенный ниже код успешно отображает карту, когда вводятся необработанные значения для широты и долготы, но, похоже, я не могу извлечь значения из своего объекта состояния для использования в render() .

Строки, отмеченные //RIGHT HERE знаком, — это то, где я хочу использовать значения lat / long, сохраненные в моем объекте состояния — прямо сейчас я установил для них константы, чтобы мое приложение функционировало.

Я попытался заменить эти константы на:

 this.state.initLat_s
this.state[initLat_s]
 

Я попытался создать другую структуру «regData» и ссылаться на нее несколькими способами, в том числе ссылаться на нее, чтобы получить всю информацию для initialRegion, включая дельты

Я создал функции «get ()» как внутри, так и за пределами состояния, которые выдавали ошибки

Я пытался создавать «глобальные» переменные — например, lat_g — с правильными значениями и ссылаться на них, используя this.lat_g , lat_g и ряд других синтаксисов, но я просто не могу заставить компилятор понять ссылку на переменную состояния из render .

 export default class App extends React.Component {

  state = { //state set
    locationResult: null, //location result holds either location object converted to string or error message as string 
    locationStatus: null, //holds success status of location grab
    initLat_s: null, //holds initial latitude and longitude of user location
    initLon_s: null
  }; 
  
  componentDidMount() {this._getLocationAsync();} //if component mounts, run location grabber
    
  _getLocationAsync = async () => { //location grabber
    let { status } = await Permissions.askAsync(Permissions.LOCATION); //ask for location perms
    if (status !== "granted") { //if location perms denied, set locationResult accordingly
      this.setState({locationResult: "Permission to access location was denied"});
      this.setState({locationStatus: false});
    } else {
      let initLocation = await Location.getCurrentPositionAsync({}); //otherwise, save location object in "location" var
      this.setState({locationResult: JSON.stringify(initLocation)}); //set locationResult to string representation of location
      this.setState({locationStatus: true});

      let {initLat, initLon} = initLocation.coords; //gather lat/lon from location object
      this.setState({initLat_s: initLat}); //set lat/lon in state accordingly
      this.setState({initLon_s: initLon});
    }
  };

  render() {
    return (
      <View style={styles.container}>
        <MapView 
          style={styles.mapStyle}
          initialRegion={{
            latitude: -30,     //RIGHT HERE
            longitude: 120,    //RIGHT HERE
            latitudeDelta: .01,
            longitudeDelta: .01 
          }}
        />
      </View>
    );
  }
}
 

Комментарии:

1. <MapView initialRegion={{ широта: {this.state.initLat_s}, долгота: {this.state.initLon_s} }}. Это не работает для вас?

2. Нет, это первое, что я попробовал, потому что я предположил, что это правильный синтаксис для JavaScript, но, похоже, он не работает :/ Он выдает «Неожиданное ключевое слово «this»» в expo, а в VSCode он выдает «: expected» от компилятора

Ответ №1:

Вы можете попробовать этот подход.

 constructor(props) {
    super(props);
    this.state = {
      locationResult: null, //location result holds either location object converted to string or error message as string 
    locationStatus: null, //holds success status of location grab
    initLat_s: null, //holds initial latitude and longitude of user location
    initLon_s: null
    }
  } 

Комментарии:

1. К сожалению, я попробовал это, и это выдает ту же ошибку, о которой я упоминал в ответе на Aymen — «Неожиданное ключевое слово «this»»

2. Возможно, это не связано с вашим свойством состояния, но вместо этого может отсутствовать конструктор и суперпроп.

3. Я не совсем уверен, что вы имеете в виду. Нужен ли мне конструктор для класса «App»? Есть ли где-нибудь, где я могу прочитать больше об этом? Кроме того, я не совсем уверен, что подразумевается под «супер опорой».

4. Это сработало, спасибо! Я не понимал, что мне нужно было создавать этот конструктор :). Функция «захват местоположения» по-прежнему не работает, поэтому она просто по умолчанию использует любые значения, установленные в объекте состояния, а не то, что получено от пользователя, но это отдельная проблема. Спасибо!

Ответ №2:

попробуйте это, и это сработает с вами.

     // Initial state shouldn't be a **null** because initialRegion.latitude and 
   // initialRegion.longitude are marked as required
    
        state = {
            initLat_s: -30, 
            initLon_s: 120,
          };
        <MapView
                  initialRegion={{
                    latitude: this.state.initLat_s, // Without {}
                    longitude: this.state.initLon_s, // Without {}
                    latitudeDelta: 0.01,
                    longitudeDelta: 0.01,
                  }}
                />
 

Комментарии:

1. Хотя это было правильно (поэтому я дал вам преимущество!), Проблема заключалась в отсутствии конструктора 🙂

2. Я рекомендую вам использовать функциональный компонент и устанавливать состояние с помощью реактивных перехватов вместо компонента класса. это просто и понятно для новичков.