当前位置: 首页 > 知识库问答 >
问题:

反应this.props未定义或空对象

阳长恨
2023-03-14

构建一个小的react应用程序,将地理位置(由浏览器确定为道具)传递给子组件。

第一个组件:app.jsx

import React, {Component} from 'react';

import DateTime from './components/dateTime/_dateTime.jsx';
import Weather from './components/weather/_weather.jsx';
import Welcome from './components/welcome/_welcome.jsx';

require ('../sass/index.scss');

export default class App extends Component {

  constructor() {
    super();
    this.state = {
      latitude: '',
      longitude: ''
    };
    this.showPosition = this.showPosition.bind(this);
  }

  startApp () {
    this.getLocation();
  }

  getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(this.showPosition);
    } else {
        console.log("Geolocation is not supported by this browser.");
    }
  }

  showPosition(position) {
    this.setState({
        latitude: position.coords.latitude,
        longitude: position.coords.longitude
    })
  }

  componentWillMount () {
    this.startApp();
  }

  render() {
    return (
        <div className="container">
            <div className="header-container">
                <Weather latitude={ this.state.latitude } longitude={ this.state.longitude } />
            <DateTime />
            </div>
            <div className="welcome-container">
                <Welcome name="Name" />
            </div>
      </div>
    );
  }
}

该组件确定位置,保存要声明的纬度和经度,并通过props将该信息传递给Weather.jsx组件,该组件正在工作,如下图所示:

在Weather.jsx组件中,我尝试访问这些道具,得到未定义的或空的对象。

import React, {Component} from 'react';
import Fetch from 'react-fetch';

export default class Weather extends Component {

    constructor(props) {
        super(props);
        this.state = {
          forecast: {},
          main: {},
          weather: {},
        };
        this.setWeather = this.setWeather.bind(this);
    }

    getWeather (latitude, longitude) {
        var self = this;

        fetch('http://api.openweathermap.org/data/2.5/weather?lat=' + latitude + '&lon=' + longitude + '&units=metric&APPID=ed066f80b6580c11d8d0b2fb71691a2c')  
            .then (function (response) {  
                if (response.status !== 200) {  
                    console.log('Looks like there was a problem. Status Code: ' + response.status);  
                    return;  
                }

                response.json().then(function(data) {  
                    self.setWeather(data);
                });
            })

            .catch (function (err) {  
                console.log('Fetch Error :-S', err);  
            });
    }

    setWeather (forecast) {
        var main = forecast.main;
        var weather = forecast.weather[0];

        this.setState({
            main: main,
            weather: weather,
            forecast: forecast
        });
    }

    startApp () {
        this.getWeather(this.props.latitude, this.props.longitude);
    }

    componentWillMount () {
        this.startApp();
    }

    componentDidMount () {
        // window.setInterval(function () {
    //          this.getWeather();
    //  }.bind(this), 1000);
    }

  render() {
    return (
        <div className="">
            <div className="weather-data">
                <span className="temp">{Math.round(this.state.main.temp)}&#176;</span>
                <h2 className="description">{this.state.weather.description}</h2>
            </div>
        </div>
    )
  }
}

真的不知道问题是什么,因为react dev tools显示weather组件确实在传递给该组件的道具中设置了位置。

编辑**已解决:

所以问题是状态是异步设置的,并且我的天气组件是在状态更新之前呈现的。

在render方法期间对state中的值进行简单检查就解决了这个问题。

render() {

    if (this.state.latitude != '' && this.state.longitude != '') {
      var weatherComponent = <Weather latitude={ this.state.latitude } longitude={ this.state.longitude } />
    } else {
      var weatherComponent = null;
    }

    return (
        <div className="container">
            <div className="header-container">
                {weatherComponent}
            <DateTime />
            </div>
            <div className="welcome-container">
                <Welcome name="Name" />
            </div>
      </div>
    );
  }

共有2个答案

弘浩瀚
2023-03-14

您必须将startApp()getWeather()绑定到组件,否则this将是未定义的

export default class Weather extends Component {

    constructor(props) {
        super(props);
        this.state = {
          forecast: {},
          main: {},
          weather: {},
        };
        this.setWeather = this.setWeather.bind(this);
        this.getWeather = this.getWeather.bind(this);
        this.startApp = this.startApp.bind(this);
    }
    ...
}
王昊
2023-03-14

我相信问题如下。SetState异步发生。正因为如此,你的渲染函数在经纬度道具有数据之前就已经开火了。如果您在呈现天气组件之前有一些If检查,那么您可能不会有这个问题。这里有一个例子说明我的意思。

render() {
    let myComponent;
    if(check if props has val) {
        myComponent = <MyComponent />
    } else {
        myComponent = null
    }
    return (
        <div>
            {myComponent}
        </div>
    )
}
 类似资料:
  • 我使用了React验证库 https://www.npmjs.com/package/react-validation 如果我从任何其他页面访问我的页面,它不会给出任何错误。但是当我刷新页面时,它给出了一个错误 无法将未定义或null转换为对象 如果有人以前遇到过这个问题,请提出一个想法。 代码:

  • 我试图通过反应路由器将道具从一个组件传递到另一个组件。当我试图从子组件获取道具时,我得到了这样一条消息。这是我的代码: Tracks.jsx: app.jsx: Album.jsx:

  • 这是因为一些只兼容客户端的脚本被打包进了服务端的执行脚本中去。 对于只适合在客户端运行的脚本,需要通过使用 process.client 变量来判断导入。 举个例子, 在你的 .vue 文件中: if (process.client) { require('external_library') }

  • 问题内容: React 在promise中没有定义。这是我的代码: 这是错误代码: 问题答案: 可能没有约束力。 如果您可以使用ES6语法,请尝试用箭头函数替换。它会自动绑定: 或手动绑定:

  • 我必须发布{输入}数据以http://localhost:4000/predictionAxios。但是{输入}变为未定义。 我使用const而不是类Main扩展组件. onChange,它设置表单数据。 阿希奥斯邮报。 返回(表单)时带有onSubmit、onChange。

  • 如果发现未定义或为空,我想在数组中按下键 我想要像这样的输出 因为a1和平台的值为null且未定义 我已经尝试过这个解决方案,但它不起作用 但是这只返回['platform'],但是预期的输出应该是['platform','a1'],我认为在运行迭代器(obj[key])时,数组的值(blankValues)变为空,因为它不能保持它,但是请帮助我使用适当的逻辑和结构