未捕获的TypeError:无法在App.render中读取null的属性“nameOfCity”

时间:2017-01-31 12:33:21

标签: javascript reactjs ecmascript-6

当我编译我的文件并在控制台日志中运行时,我收到此错误

enter code here
Uncaught TypeError: Cannot read property 'nameOfCity' of null     at App.render

他们都在App组件“见面”(我正在使用来自facebook的'create-react-app'包)。我假设它应该加载第一个Form Container并在其中逻辑设置初始状态为空,然后天气信息数据到来。或者我错了吗?

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import {FormContainer} from './containers/FormContainer';
import WeatherInfo from './components/WeatherInfo';

class App extends Component {

render() {
return (
  <div className="App">
    <div className="App-header">
      <img src={logo} className="App-logo" alt="logo" />
      <h2>Weather App</h2>
    </div>
    <p className="App-intro">
      To get started, edit <code>src/App.js</code> and save to reload.
    </p>
      <FormContainer label="Name of the city:"/>
      <WeatherInfo
          nameOfCity={this.state.nameOfCity}
          weatherDescription={this.state.weatherDescription}
          windSpeed={this.state.windSpeed}
          temperature={this.state.temperature}
          maxTemperature={this.state.maxTemperature}
          minTemperature={this.state.minTemperature}
      />
  </div>
);
}
}
export default App;

表格容器

import React, {Component} from 'react';
import SearchBar from '../components/SearchBar';

class FormContainer extends Component {

constructor(props) {
    super(props);
    this.state = {
        cityName: '',
        nameOfCity:'',
        weatherDescription:'',
        windSpeed:'',
        temperature:'',
        maxTemperature:'',
        minTemperature:''
    };
    this.handleFormSubmit = this.handleFormSubmit.bind(this);
    this.handleCityName = this.handleCityName.bind(this);
}

handleFormSubmit(e) {
    e.preventDefault();

    const SendForm = {
        cityName: this.state.cityName
    };
    console.log(SendForm);
    fetch(`http://api.openweathermap.org/data/2.5/forecast/weather?q=${SendForm.cityName}&units=metric&APPID=********`)
        .then(res => res.json())
        .then(results => {
            this.setState({
                nameOfCity: results.city.name,
                weatherDescription: results.list[0].weather[0].description,
                windSpeed: results.list[2].wind.speed,
                temperature: results.list[0].main.temp,
                maxTemperature: results.list[0].main.temp_max,
                minTemperature: results.list[0].main.temp_min
            });
        });
}

handleCityName(value) {
    this.setState({ cityName: value });
}

render() {
    return (
        <div>
        <form onSubmit={this.handleFormSubmit}>
            <label>{this.props.label}</label>
            <SearchBar
                name="CityName"
                type="text"
                value={this.state.cityName}
                placeholder="search"
                onChange={this.handleCityName}
            />
            <button type="submit"
                    className=""
                    value='Submit'
                    placeholder="Search" />
        </form>

        </div>
    );
}
}

export {FormContainer};

搜索栏组件

import React, {Component} from 'react';

const SearchBar = (props) => (
<div>
    <label>{props.label}</label>
    <input name={props.name} type={props.inputType} value={props.value} placeholder={props.placeholder} onChange={(e)=>props.onChange(e.target.value)}/>
</div>
);

export default SearchBar;

和天气信息组件

import React, {Component} from 'react';

const WeatherInfo = (props) => (
<div>
    <ul>
        <li>{props.nameOfCity}</li>
        <li>{props.weatherDescription}</li>
        <li>{props.windSpeed}</li>
        <li>{props.temperature}</li>
        <li>{props.maxTemperature}</li>
        <li>{props.minTemperature}</li>
    </ul>
</div>
);

export default WeatherInfo;

4 个答案:

答案 0 :(得分:1)

错误发生在<WeatherInfo nameOfCity={this.state.nameOfCity},因为此时您在nameOfCity组件状态中没有App

在您的代码中,nameOfCity变量位于FormContainer组件状态内。如果要在组件中使用它,则应在App组件处具有状态。

答案 1 :(得分:1)

您尝试从App中的this.state读取nameOfCity,但您的App组件未保持状态。

您可以使用FormContainer使用上下文并将WeatherInfo渲染为子项:

       if event.key == pygame.K_w:
          p.fov.y -= g.pixelUpdate
          for ent in w.entityList:
            ent.rect.y += g.pixelUpdate
            ent.collisionRect.y += g.pixelUpdate
          for ent in w.ents_in_fov:
            if p.collision(ent):
              p.collided = True
              for ent in w.entityList:
                ent.rect.y -= g.pixelUpdate
                ent.collisionRect.y -= g.pixelUpdate
              p.fov.y += g.pixelUpdate

        elif event.key == pygame.K_d:
          p.fov.x += g.pixelUpdate
          for ent in w.entityList:
            ent.rect.x -= g.pixelUpdate
            ent.collisionRect.x -= g.pixelUpdate
          for ent in w.ents_in_fov:
            if p.collision(ent):
              p.collided = True
              for ent in w.entityList:
                ent.rect.x += g.pixelUpdate
                ent.collisionRect.x += g.pixelUpdate
              p.fov.x -= g.pixelUpdate

        elif event.key == pygame.K_s:
          p.fov.y += g.pixelUpdate
          for ent in w.entityList:
            ent.rect.y -= g.pixelUpdate
            ent.collisionRect.y -= g.pixelUpdate
          for ent in w.ents_in_fov:
            if p.collision(ent):
              p.collided = True
              for ent in w.entityList: 
                ent.rect.y += g.pixelUpdate
                ent.collisionRect.y += g.pixelUpdate
              p.fov.y -= g.pixelUpdate

        elif event.key == pygame.K_a:
          p.fov.x -= g.pixelUpdate
          for ent in w.entityList:
            ent.rect.x += g.pixelUpdate
            ent.collisionRect.x += g.pixelUpdate
          for ent in w.ents_in_fov:
            if p.collision(ent):
              p.collided = True
              for ent in w.entityList:
                ent.rect.x -= g.pixelUpdate
                ent.collisionRect.x -= g.pixelUpdate
              p.fov.x += g.pixelUpdate

App.jsx:

class FormContainer extends Component {
  ...
  static childContextTypes = {
    nameOfCity: React.PropTypes.string
  }
  getChildContext() {
    return {
      nameOfCity: this.state.nameOfCity
    }
  }
 render: () {
   ...
   </form>
   {this.children}
 }

}

WeatherInfo.jsx:

<FormContainer label="Name of the City:">
  <WeatherInfo />
</FormContainer>

或者你可以在App中存储状态,并让FormContainer通过传递prop或使用上下文来更改App.state。

答案 2 :(得分:0)

问题是你在this.state使用App componentApp component你没有定义任何state,这就是为什么它会抛出错误can't read Cannot read property 'nameOfCity' of null,因为statenull。您需要在state中定义App component,然后在state中传递此props个值,并在其他component中使用这些值。

答案 3 :(得分:0)

当您尝试使用非现有数据的属性时,会发生这种类型的错误。在这种情况下,this.state没有值,即 null 。因此,请确保您的 this.state 根据您的功能通过某些操作获得所需的价值。