ReactJS生命周期方法无法按顺序运行

时间:2019-03-23 06:55:54

标签: javascript reactjs react-router react-google-maps

我正在使用ReactJS进行Google Maps渲染。为此,我正在使用“ react-google-maps”库。逻辑流程是;在页面加载时,获取用户的位置并将其绘制在地图上。 向用户提供了导航链接以点击不同的URL。为了处理导航,我使用了React Router。在componentWillMount()中标识用户的位置,然后相应地设置状态,并在render()中渲染地图。 问题在于,在完成componentWillMount()之前会先调用render(),它会获取null值,然后失败。这种情况仅发生在客户端路由中,而不发生在服务器端渲染中。

为了限制执行方式,我将componentWillMount()用作异步方法,在该方法中它一直等待直到确定用户的位置为止。仍然没有帮助。

state = {
        homeLocation: {},
        coordinates: []
    }

async componentWillMount(props) {
        const { lat,lng } = await this.getcurrentLocation();
        this.setState({
            homeLocation:{
                lat: lat, 
                lng: lng
            }
        })
    }

getcurrentLocation() {

        if (window.navigator && window.navigator.geolocation) {
          return new Promise((resolve, reject) => {
            window.navigator.geolocation.getCurrentPosition(pos => {
              const coords = pos.coords;
              resolve({
                lat: coords.latitude,
                lng: coords.longitude
              });
            });
          });
        }
        return {
          lat: 0,
          lng: 0
        };
      }
render(){

   <MapWithAMarker
   // necessary parameters
  />
}

//Routers
const AppRouter = () => (
    <Router>
        <div>
            <Switch>
                <Route path="/" component={MapHomeLocation} exact={true}/>
                <Route path="/location/:locationType" component={MapSelectedLocation}/>
                <Route component={Notfound}/>
            </Switch>
        </div>

    </Router>
);


The expected result is that coordinates should be determined first then render() should get called. In server-side routing(i.e. using anchor tags instead of <Link>) it works as expected.

3 个答案:

答案 0 :(得分:1)

在状态本身中调用getcurrentLocation()。

state = {
        homeLocation: this.getcurrentLocation(),
        coordinates: []
    }



getcurrentLocation() {

        if (window.navigator && window.navigator.geolocation) {
          return new Promise((resolve, reject) => {
            window.navigator.geolocation.getCurrentPosition(pos => {
              const coords = pos.coords;
              resolve({
                lat: coords.latitude,
                lng: coords.longitude
              });
            });
          });
        }
        return {
          lat: 0,
          lng: 0
        };
      }
render(){

   <MapWithAMarker
   // necessary parameters
  />
}

//Routers
const AppRouter = () => (
    <Router>
        <div>
            <Switch>
                <Route path="/" component={MapHomeLocation} exact={true}/>
                <Route path="/location/:locationType" component={MapSelectedLocation}/>
                <Route component={Notfound}/>
            </Switch>
        </div>

    </Router>
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

答案 1 :(得分:1)

您应该检查是否有数据,然后才给出值。

如果data && data.length> 0?数据:空

答案 2 :(得分:1)

永远不要在componentWillMount()中进行获取操作,而应使用componentDidMount(),因为调用setState()会重新渲染该组件,您可能会看到新数据出现在地图上。