TypeError:this.props.weather未定义

时间:2018-11-03 08:37:19

标签: javascript reactjs redux react-redux redux-promise

我正在开发一个应用程序,它将帮助我使用openweathermap.org获取任何城市的五天天气预报,但是,每当我在WeatherList容器中调用函数renderWeather时,都会在浏览器中收到上述错误,如图所示在下面的代码段中。

此文件是我导入redux promise的index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import ReduxPromise from 'redux-promise';

import App from './components/app';
import reducers from './reducers';

const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <App />
  </Provider>
  , document.querySelector('.container'));

weather_list容器的代码如下

import React, {Component} from 'react';
import {connect} from 'react-redux';

class WeatherList extends Component{

renderWeather(cityData){
  return(
    <tr>
      <td>{cityData.city.name}</td>
    </tr>
  );

}

  render(){
    return(
      <table className="table table-hover">
        <thead>
          <tr>
          <th>City</th>
          <th>Temperature</th>
          <th>Pressure</th>
          <th>Humidity</th>
          </tr>
        </thead>
        <tbody>
        {this.props.weather.map(this.renderWeather)}
        </tbody>
      </table>
    );
  }
}
function mapStateToProps(state){
  return {
    weather: state.weather
  };
}
export default connect(mapStateToProps)(WeatherList);

search_bar容器的代码如下

import React, {Component}from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {fetchWeather} from '../actions/index';

class SearchBar extends Component{
  constructor(props){
    super(props);

    this.state = {term: ''};
    this.onInputChange = this.onInputChange.bind(this);
    this.onFormSubmit = this.onFormSubmit.bind(this);
  }

onInputChange(event){
  console.log(event.target.value);
  this.setState({term: event.target.value});
}

onFormSubmit(event){
  event.preventDefault();
  // we need to go and fetch weather data!
  this.props.fetchWeather(this.state.term);
  this.setState({term: ''});
}

  render(){
    return(
      <form onSubmit={this.onFormSubmit} className="input-group">
        <input
          placeholder="Get a five-day forecast in your favorite cities"
          className="form-control"
          value={this.state.term}
          onChange={this.onInputChange} />
        <span className="input-group-btn">
          <button type="submit" className="btn btn-secondary">Submit</button>
        </span>
      </form>
    );
  }
}
function mapDispatchToProps(dispatch){
  return bindActionCreators({fetchWeather:fetchWeather}, dispatch)
}

export default connect(null, mapDispatchToProps)(SearchBar);

该应用程序组件的代码如下所示

import React, { Component } from 'react';
import SearchBar from '../containers/search_bar.js';
import WeatherList from '../containers/weather_list.js';


export default class App extends Component {
  render() {
    return (
      <div>
        <SearchBar />
        <WeatherList />
      </div>
    );
  }
}

如下所示的降温器代码

import {FETCH_WEATHER} from '../actions/index';

export default function(state = [], action){
  switch (action.type) {
    case FETCH_WEATHER:
      //return state.concat([action.payload.data]);
      return ([action.payload.data, ...state])
  }
  return state;
}

reducers文件夹中index.js的代码如下所示

import { combineReducers } from 'redux';
import WeatherReducer from './reducer_weather';

const rootReducer = combineReducers({
  weather: WeatherReducer
});

export default rootReducer;

动作文件夹中动作创建者的代码如下所示

import axios from 'axios';
const API_KEY = '03d17752ca362bc60ca7df94aac228a6';
const ROOT_URL =`https://api.openweathermap.org/data/2.5/forecast?appid=${API_KEY}`;

export const FETCH_WEATHER = 'FETCH_WEATHER';

export function fetchWeather(city){
  const url = `${ROOT_URL}&q=${city},us`;
  const request = axios.get(url);

  console.log('Request:', request);

  return{
    type: FETCH_WEATHER,
    payload: request
  }
}

最后,下面的图片显示了浏览器中的错误。 enter image description here

非常感谢您提供解决错误的方法

2 个答案:

答案 0 :(得分:1)

最初,this.props.weather是未定义的,因此您需要像两种方式一样在执行.map之前进行条件检查

this.props.weather && this.props.weather.map

OR

Array.isArray(this.props.weather) && this.props.weather.map

此外,在执行.map时,您还需要将天气数据传递给renderWeather方法,因为它需要数据,但是您没有在.map中传递数据给它

更改

{this.props.weather.map(this.renderWeather)}

收件人

 {Array.isArray(this.props.weather) && this.props.weather.map(item => this.renderWeather(item))}

还在此处为tr元素设置唯一键

renderWeather(cityData){
  return(
    <tr key={cityData.city && cityData.city.id}> //if you do not have unique id then use index as key
      <td>{cityData.city && cityData.city.name}</td>
    </tr>
  ); 
}

或者如果您的数据不包含唯一ID,则使用索引作为键

 {Array.isArray(this.props.weather) && this.props.weather.map((item, index) => this.renderWeather(item, index))}

还在此处为tr元素设置唯一键

renderWeather(cityData, index){
  return(
    <tr key={"city-"+index}> //if you do not have unique id then use index as key
      <td>{cityData.city && cityData.city.name}</td>
    </tr>
  ); 
}

答案 1 :(得分:0)

这是因为this.props.weatherundefined,因此在.map()上调用undefined函数将引发错误。您可以在前面添加验证,以确保仅在数组(数据输入时)时才调用.map()

您可以添加:

Array.isArray(this.props.weather) && ...

在此处进行更改:

import React, {Component} from 'react';
import {connect} from 'react-redux';

class WeatherList extends Component{

renderWeather(cityData){
  return(
    <tr>
      <td>{cityData.city.name}</td>
    </tr>
  );

}

  render(){
    return(
      <table className="table table-hover">
        <thead>
          <tr>
          <th>City</th>
          <th>Temperature</th>
          <th>Pressure</th>
          <th>Humidity</th>
          </tr>
        </thead>
        <tbody>
        {Array.isArray(this.props.weather) && this.props.weather.map(this.renderWeather)}
        </tbody>
      </table>
    );
  }
}
function mapStateToProps(state){
  return {
    weather: state.weather
  };
}
export default connect(mapStateToProps)(WeatherList);