一旦状态中的数据不为空,则ReactJS显示组件

时间:2018-03-02 09:59:02

标签: javascript reactjs

编辑:所以我遇到了一些堆栈溢出的麻烦,不得不重新输入一些东西....包括Weather weatherData = {this.state.weatherData}我在这里不小心输错了天气weatherData = {weatherData}。但我也在我的代码上输入了错误,那就是setState。我是新的reactjs和一些我发现很奇怪的语法,所以这可能是我有语法错误的原因。所以我最终修复了一些东西,但仍然有一个错误“this.setState不是一个函数”。我想也许这是一个范围问题,所以我创建了一个新方法updateWeatherData,并且有效。

所以我想制作一个天气应用程序。我想要做的是在this.state.weatherData中有数据后加载名为Weather的子组件。我已经使用console.log进行了检查,数据是从ajax调用回来的,但我似乎无法设置它。我得到的错误信息是“无法读取未定义的属性'weatherData'”

var React = require('react');
var Weather = require('./Weather');


class App extends React.Component{
    constructor(props)
    {
        super(props);
        this.state = {
            weatherData: null,
        };
        this.getDataFromLatLng = this.getDataFromLatLng.bind(this);
        this.showPosition = this.showPosition.bind(this);
    }
    updateWeatherData (results)
    {
        this.setState({
            weatherData:results
        });
    }
    componentDidMount()
    {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(this.showPosition);

        } else {
            alert("Geolocation is not supported by this browser.");
        }
    }
    showPosition(position)
    {
        this.getDataFromLatLng(position.coords.latitude, position.coords.longitude);
    }
    getDataFromLatLng(lat, lng)
    {
        $.ajax({
            url: 'http://api.openweathermap.org/data/2.5/weather?lat='+lat+'&lon='+lng+"&units=metric&appid=ID",
            type:"GET",
            dataType:"jsonp",
             //CHANGED FROM THIS:
            /*success:function(results){
                //RESULTS COME BACK
                console.log(results);
                this.setState=({
                    weatherData:results
                });
                console.log(this.state.weatherData);
                //But no weatherData is being set

            },*/
            //TO THIS:
            success:this.updateWeatherData,
            error: function(xhr, status, error) {
              console.log(xhr.responseText + " " + status, " " + error);
            }
        });
    }
    render()
    {
        return(
            <div id="container">
                Hello From App
                {this.state.weatherData != null
                    ? <Weather weatherData={this.state.weatherData}/>
                    : <p>Loading...</p>
                }

            </div>
        );
    }
}

module.exports = App;

2 个答案:

答案 0 :(得分:2)

<Weather weatherData={weatherData}/>更改为<Weather weatherData={this.state.weatherData}/>

关于为什么console.log(this.state.weatherData)没有显示您设置的值,这是因为setState是异步的。请参阅this article

具体来说,我指的是文章中的以下几行:

// assuming this.state = { value: 0 }
this.setState({
  value: 1
});
console.log(this.state.value); // 0

答案 1 :(得分:0)

 <div id="container">
            Hello From App
            {this.state.weatherData != null
                ? <Weather weatherData={weatherData}/>
                : <p>Loading...</p>
            }

        </div>

这里如果你看到你的代码,你想要它渲染一次this.state.weatherData有一些东西。所以我们说它已经有了,现在是时候渲染了。你正在渲染的组件正在被赋予道具作为weatherData ...但你没有在任何地方定义它。你真的想要通过

的状态
 <div id="container">
            Hello From App
            {this.state.weatherData != null
                ? <Weather weatherData={this.state.weatherData}/>
                : <p>Loading...</p>
            }

        </div>

因为

而无法看到它
  //RESULTS COME BACK
            console.log(results);


            this.setState=({
                weatherData:results
            });
            console.log(this.state.weatherData);
            //But no weatherData is being set

结果来了,你setState结果。然而,这不是一个你可以设置值的对象..它将被调用,反应将做它的事情并更新状态但它不会在继续前进之前完成它。它只是向前移动并在后台异步进行。一旦getDataFromLatLng完成,将调用渲染,你应该总是在render方法中检查更新的状态..

render(){
   console.log(this.state.weatherData);
   // Your Code here
}

您将在那里看到更新后的状态。 至于你在哪里传递道具作为weatherData而不是this.state.weatherData,如果你打算在渲染中使用它,就像你使用两次一样。如果你愿意,可以这样使用它。这称为Object destructuring

render(){
  const {weatherData} = this.state ;
 return(
        <div id="container">
            Hello From App
            {weatherData != null
                ? <Weather weatherData={weatherData}/>
                : <p>Loading...</p>
            }

        </div>
    );
}

您现在可以使用weatherData而不是this.state.weatherData。我们在这里使用const来声明因为状态是不可变的,所以你不要错误地在渲染中改变它。