React-天然:getCurrentLocation的设置状态()=空

uurity8g  于 2023-02-19  发布在  React
关注(0)|答案(1)|浏览(125)

我想得到我的任务的距离,这些任务是带有lat lng值的对象。它们保存在我的firebase数据库中。
现在我的问题是,我在componentWillMount中通过setState设置用户的当前位置,但是当我从异步任务(firebase查询)调用getDistance时,用户当前位置的状态为空。
我认为发生这种情况是因为操作不在同一上下文中。所以我试图深入研究Redux,但无法掌握这个主题。
我该怎么解决这个问题?

getDistance(latitude, longitude) {
        let c = geolib.getDistance(
          { latitude: { latitude }, longitude: { longitude } }, // strawa
          { latitude: this.state.latitude, longitude: this.state.longitude }, // sbg
          100,
          1
        );
        return c / 1000;
        //alert(c / 1000); // 25km
      }
    
      /*
          Get the Users current location
          iOS -> asks only one time for permission, so pay attention if disabled !!!
      */
      getCurrentLocation() {
        var loc;
        navigator.geolocation.getCurrentPosition(
          position => {
            console.log("Location Request - Position = " + position);
            this.setState({
              latitude: position.coords.latitude,
              longitude: position.coords.longitude
            });
          },
          error => this.setState({ error: error.message }),
          { enableHighAccuracy: false, timeout: 200000, maximumAge: 1000 }
        );
      }
    
      componentWillMount() {
        //this.getCurrentLocation();
        this.listenForTasks(this.tasksRef);
      }

  listenForTasks(tasksRef) {
    tasksRef.on("value", snap => {
      var tasks = [];
      snap.forEach(child => {
        // If Task_Type = 0 getDistance
        var distance = "";
        if (child.val().type === "0") {
          distance = this.getDistance(child.val().lat, child.val().lng);
        } else {
          distance = "Online";
        }
        tasks.push({
          title: child.val().title,
          budget: child.val().budget,
          offersCount: child.val().offersCount,
          commentsCount: child.val().commentsCount,
          distance: distance
        });
      });
      tasks.reverse();
      this.setState({
        dataSource: this.state.dataSource.cloneWithRows(tasks)
      });
    });
  }

这是我尝试以一种非常简单的方式实现redux的错误,但我得到了一个错误:“侦听器应为函数”

import { createStore } from "redux";

const reducer = (state = [], action) => {
  if (action.type === "getCurrentLocation") {
    return action.payload;
  }
  return state;
};
const store = createStore(reducer);

class TaskBrowseScreen extends React.Component {
  constructor(props) {
    super(props);

    store.dispatch({ type: "getCurrentLocation", payload: "?" });
    store.subscribe();
...
ljsrvy3e

ljsrvy3e1#

首先,您不应该在componentWillMount =〉why?手册中这样做
出现此问题的原因是您未链接呼叫。最好在从geolocation设置位置后立即呼叫getDistance
最简单的方式就是回报一个承诺:

constructor() {
  super();

  this.getCurrentLocation().then(() => {
    this.listenForTasks();
  });
}

getCurrentLocation() {
  let resolver;
  let rejector;
  const promise = new Promise((resolve, reject) => {
    resolver = resolve;
    rejector = reject;
  });
  var loc;
  navigator.geolocation.getCurrentPosition(
    position => {
      console.log("Location Request - Position = " + position);
      this.setState({
        latitude: position.coords.latitude,
        longitude: position.coords.longitude
      }, resolver);
    },
    error => this.setState({ error: error.message }, rejector),
    { enableHighAccuracy: false, timeout: 200000, maximumAge: 1000 }
  );

  return promise;
}

UPD:这对你来说可能很重要,不要花时间去一个接一个的链接所有的异步方法。然后你可以在调用getDistance之前存储这个承诺并做一个链接:

constructor() {
  super();

  this._promise = this.getCurrentLocation();
  this.listenForTasks();
}

listenForTasks() {
  // some async
    this._promise.then(() => {
      this.getDistance();
    });
}

这将可能你不花时间,并呼吁db.call并行。

相关问题