2017-05-29 11 views
0

Nur um zu erwähnen, habe ich keine Antworten für meine besondere Situation auf ähnlichen Post gefunden.this.props.myActionCreator wirft 'TypeError: Kann Eigenschaft' Requisiten 'von Null nicht lesen'

Meine App ermöglicht es einem Benutzer, das Wetter einer Stadt zusammen mit einer relevanten Packliste für dieses Wetter zu erhalten.

Ich möchte die Karte jeder Stadt löschbar machen und ein 'X' platzieren, das einen updateTerms-Aktions-Ersteller aufrufen sollte, der es wiederum aus der Benutzerliste entfernen und das Dom aktualisieren würde.

Der Rückruf zu Feuer scheint, aber this.props.updateTerms wirft ** Typeerror: kann Eigenschaft 'Requisiten' von null bei handleDeleteCard **

a_result_card.js lesen

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
import ATodoList from './a_Todo_List'; 
import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'; 
import { bindActionCreators} from 'redux'; 
import { updateTerms } from '../actions'; 

class AResultCard extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { cityName : '' }; 
     this.handleDeleteCard = this.handleDeleteCard.bind(this); 
    } 

    handleDeleteCard(event) { // I NEED TO CALL THIS WITH THE KEY 
     //So THAT I CAN REMOVE IT FROM THE USERS TERM LIST 
     event.preventDefault(); 
     debugger; 
     this.props.updateTerms(cityName, "delete"); 
    } 

    renderWeather(cityData) { 
     function calcAverageTemp(days) { 
      let reduced = days.reduce((sum,day) => { 
       return sum + day.main.temp_max; 
      }, 0); 
      return Math.floor(reduced/cityData.list.length); 
     }; 
     function calcAverageHumidity(days) { 
      let reduced = days.reduce((sum,day) => { 
       return sum + day.main.humidity; 
      }, 0); 
      return Math.floor(reduced/cityData.list.length); 
     }; 
     const avgTempK = calcAverageTemp(cityData.list); 
     const cityName = cityData.city.name; 
     const avgTempF = Math.floor((avgTempK * 1.8) - 459.67); 
     const avgHumidity = calcAverageHumidity(cityData.list); 

     return (
      <li key={cityName} className="result-card"> 
       <div className="card"> 
        <div className=""> 
         <div className="weather-details"> 
          <div className="card-heading"> 
           <span className="weather-detail detail-title">{cityName}</span> 
           <span className="weather-detail">{avgTempF} &#176;F</span> 
           <span className="weather-detail">H: {avgHumidity}%</span> 
           <span className="weather-detail delete-card-icon" onClick={handleDeleteCard}>X</span> 
          </div> 
         </div> 
         <ATodoList avgTempF={avgTempF} /> 
        </div> 
       </div> 
      </li> 
     ); 
    } 


    render() { 
     return (
      <ul className="results"> 
       <CSSTransitionGroup 
        transitionName="example" 
        transitionEnterTimeout={150} 
        transitionLeaveTimeout={150}> 

       {this.props.weather.map(this.renderWeather)} 
       </CSSTransitionGroup> 
      </ul> 
     ); 
    } 
} 

function mapStateToProps({weather, userTerms}) { 
    return ({ 
      weather, 
      userTerms 
     }); 
} 
function mapDispatchToProps(dispatch) { 
    return bindActionCreators({ updateTerms }, dispatch); 
} 

export default connect(mapStateToProps, mapDispatchToProps)(AResultCard); 
+0

Können Sie versuchen, die onClick Funktion wie diese Aufruf - 'onClick = {this.handleDeleteCard}' – nrgwsth

+0

Dieser Teil war der Lösung, danke. :) – Zach

Antwort

0

Sie benötigen handleDeleteCard Funktion wie

<span className="weather-detail delete-card-icon" onClick={this.handleDeleteCard}>X</span> 

da es nennen b elongs auf den Kontext des React Component und nicht die renderWeather Funktion

binden auch die renderWeather Funktion

renderWeather = (cityData) => { 
    function calcAverageTemp(days) { 
     let reduced = days.reduce((sum,day) => { 
      return sum + day.main.temp_max; 
     }, 0); 
     return Math.floor(reduced/cityData.list.length); 
    }; 
    function calcAverageHumidity(days) { 
     let reduced = days.reduce((sum,day) => { 
      return sum + day.main.humidity; 
     }, 0); 
     return Math.floor(reduced/cityData.list.length); 
    }; 
    const avgTempK = calcAverageTemp(cityData.list); 
    const cityName = cityData.city.name; 
    const avgTempF = Math.floor((avgTempK * 1.8) - 459.67); 
    const avgHumidity = calcAverageHumidity(cityData.list); 

    return (
     <li key={cityName} className="result-card"> 
      <div className="card"> 
       <div className=""> 
        <div className="weather-details"> 
         <div className="card-heading"> 
          <span className="weather-detail detail-title">{cityName}</span> 
          <span className="weather-detail">{avgTempF} &#176;F</span> 
          <span className="weather-detail">H: {avgHumidity}%</span> 
          <span className="weather-detail delete-card-icon" onClick={this.handleDeleteCard}>X</span> 
         </div> 
        </div> 
        <ATodoList avgTempF={avgTempF} /> 
       </div> 
      </div> 
     </li> 
    ); 
} 
+0

Ihre Lösung hat funktioniert. Ich hatte vergessen, dass die Verwendung des Pfeiloperators den Bereich anders behandelt. Vielen Dank! – Zach

+0

Übrigens, ich möchte den cityName in den Aktionsersteller eingeben, aber er wird derzeit in renderWeather generiert. Wenn Sie Ideen zur besseren Organisation meiner Daten haben, bin ich offen für Vorschläge. :) – Zach

Verwandte Themen