2017-12-15 22 views
0

私の天気予報アプリケーションでは、カスタム経度と緯度で書き込み可能なシステムを作成しています。両方を受信すると、小道具を使用して子コンポーネントに渡されます。そこでは、API呼び出しに追加され、その領域のデータがプルされます。天気予報、React、Propを受信しない、更新しない

APIリクエストにlong/latを手動で入力するとすべて機能しますが、propを正しく受け取ることはできません。現在、テストフィールドに入力したすべての文字は、両方のコンポーネントの連鎖反応のように見えます。子供が受け取っている小道具も未定義です。

これは私のための学習体験であり、助力をいただければ幸いです。

目的:longとlatの両方が送信されるのを待ってから、API呼び出しに追加されます。

コード:

weatherView.js:APIが呼び出され、すべてがレンダリングされた子:長いと緯度が

import React, { Component } from 'react'; 
import { WeatherCard } from './weatherCard'; 

export class WeatherView extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      lat: " ", 
      long: " ", 
      valueLat: " ", 
      valueLong: " ", 
      latBool: false, 
      longBool: false, 
      latLong: " " 
     } 
    } 

    onChangeLat = (e) => { 
     this.setState({valueLat: e.target.value}); 
    } 

    onChangeLong = (e) => { 
     this.setState({valueLong: e.target.value}); 
     console.log('Value is' + this.state.valueLong) 
    } 

    onSubmitLat = (e) => { 
     e.preventDefault() 
     if (this.state.valueLat === " ") { 
      alert("You must enter something"); 
     } else { 
      this.setState({ 
       lat: this.state.valueLat, 
       latBool: true 
      }) 
      console.log(this.state.valueLat) 
     } 
    } 

    onSubmitLong = (e) => { 
     e.preventDefault() 
     if (this.state.valueLong === " ") { 
      alert("You must enter something"); 
     } else { 
      this.setState({ 
       long: this.state.valueLong, 
       longBool: true 
      }) 
      console.log(this.state.valueLong) 
     } 
    } 



    componentDidMount(){ 

     if(this.state.latBool === true && this.state.longBool === true) { 
      this.setState({ 
       latLong: this.state.lat + "," + this.state.long 
      }) 

     } 
    } 

    render() { 
     return(
      <div> 
       <h1>Welcome to the Weather App!</h1> 
       <form onSubmit={this.onSubmitLat}> 
        Enter the Latitude in decimal format: <input type="text" value={this.state.valueLat} onChange={this.onChangeLat}/> 
        <button >Submit</button> 
       </form> 
       <form onSubmit={this.onSubmitLong}> 
        Enter the Longitude in decimal format: <input type="text" value={this.state.valueLong} onChange={this.onChangeLong}/> 
        <button>Submit</button> 
       </form> 
       <WeatherCard latLong = {this.state.latLong}/> 
      </div> 
     ) 
    } 
} 

weatherCard.jsが入力されます。

import React, { Component } from 'react'; 
import ReactAnimatedWeather from 'react-animated-weather'; 

const defaults = [ 
{ 
    icon: 'CLEAR_DAY', 
    color: 'white', 
    size: 175, 
    animate: true 
}, 
{ 
    icon: 'CLEAR_NIGHT', 
    color: 'white', 
    size: 175, 
    animate: true 
}, 
{ 
    icon: 'PARTLY_CLOUDY_DAY', 
    color: 'white', 
    size: 175, 
    animate: true 
}, 
{ 
    icon: 'PARTLY_CLOUDY_NIGHT', 
    color: 'white', 
    size: 175, 
    animate: true 
}, 
{ 
    icon: 'CLOUDY', 
    color: 'white', 
    size: 175, 
    animate: true 
}, 
{ 
    icon: 'RAIN', 
    color: 'white', 
    size: 175, 
    animate: true 
}, 
{ 
    icon: 'SLEET', 
    color: 'white', 
    size: 175, 
    animate: true 
}, 
{ 
    icon: 'SNOW', 
    color: 'white', 
    size: 175, 
    animate: true 
}, 
{ 
    icon: 'WIND', 
    color: 'white', 
    size: 175, 
    animate: true 
}, 
{ 
    icon: 'FOG', 
    color: 'white', 
    size: 175, 
    animate: true 
} 
]; 


function iconConverter(arg){ 
    switch (arg) { 
     case 'clear-day': return 0; 
      break; 
     case 'clear-night': return 1; 
      break; 
     case 'partly-cloudy-day': return 2; 
      break; 
     case 'partly-cloudy-night': return 3; 
      break; 
     case 'cloudy': return 4; 
      break; 
     case 'rain': return 5; 
      break; 
     case 'sleet': return 6; 
      break; 
     case 'snow': return 7; 
      break; 
     case 'wind': return 8; 
      break; 
     case 'fog': return 9; 
      break; 

    } 
} 

const WCard = ({day, high, low, humidity, summary, sunrise, sunset, windspeed, time, rainProb, icon}) =>{ 
    return (
     <div> 
      <p>{time}</p> 
      <div id='wCardIcon'> 

       <ReactAnimatedWeather 

        icon={defaults[iconConverter(icon)].icon} 
        color={defaults[iconConverter(icon)].color} 
        size={defaults[iconConverter(icon)].size} 
        animate={defaults[iconConverter(icon)].animate} 
        /> 
       <div> 
        <p>&#8679; {high}&#8457;</p> 
        <p>{low}&#8457; &#8681;</p> 
       </div> 
      </div> 
      <p id="wCardSum">{summary}</p> 
      <p>Humidity: {humidity}%</p> 
      <p>Wind speed: {windspeed}mph</p> 
      <p>Sunrise: {sunrise}</p> 
      <p>Sunset: {sunset}</p> 
      <p>Chance of rain: {rainProb}%</p> 

     </div> 
    )}; 



// const weatherAPI = 'https://api.darksky.net/forecast/926bb6de03f1ae8575d48aaeb2fc9b83/34.0522,-118.2437'; 

const weatherAPI = 'https://api.darksky.net/forecast/926bb6de03f1ae8575d48aaeb2fc9b83/'; 

export class WeatherCard extends Component { 
    constructor(props) { 
     super(props) 
     this.state = { 
      requestFailed: false, 
      info: '', 
      latLongSubmitted: false, 
      latLongValue: this.props.latLong, 
      weatherAPI: 'https://api.darksky.net/forecast/926bb6de03f1ae8575d48aaeb2fc9b83/' 
     } 
    } 



    componentWillReceiveProps(nextProps){ 

     console.log("Receive Props activated") 
     console.log("Prop: " + this.props.latLong) 
     console.log("Value for API" + this.latLongValue) 

     if(this.props.latLong !== nextProps.latLong) { 
      this.setState({ 
       latLongValue: nextProps.latLong, 
       latLongSubmitted: true 
      })  
      console.log(this.latLongValue) 
     } 
    } 

    shouldComponentUpdate(nextProps) { 
     console.log('shouldComponentUpdate activated'); 
    return this.state.latLongValue !== nextProps.latLongValue; 
} 

    timeDateConverter(tempTime) { 
     var time = tempTime *1000; 
     var d = new Date(time); 
     var formattedDate = (d.getMonth() + 1) + "/" + d.getDate() + "/" + d.getFullYear(); 

     return formattedDate 
    } 

    removeMilitary(hours){ 

     if (hours > 0 && hours <= 12) { 
      hours = "" + hours; 
     } else if (hours > 12) { 
      hours = "" + (hours - 12); 
     } else if (hours === 0) { 
      hours= "12"; 
     } 
     return hours; 
    } 

    timeConverter(tempTime) { 
     var time = tempTime *1000; 
     var d = new Date(time); 
     var hours = d.getHours(); 
     if (hours>=12){     //Adding endings 
       var suffix = "P.M.";} 
      else{ 
       suffix = "A.M.";} 
     var minutes = (d.getMinutes() < 10) ? "0" + d.getMinutes() : d.getMinutes(); 

     hours = this.removeMilitary(hours); 

     var formattedTime = hours + ":" + minutes + " " + suffix; 

     return formattedTime; 
    } 

    componentDidMount() { 
     if (this.state.latLongSubmitted) 
      console.log('componentDidMount is running') 
      fetch(this.state.weatherAPI + this.state.latLongValue) 
      .then(response => { 
       if (!response.ok) { 
        throw Error("Network request failed") 
       } 
       return response; 
      }) 
      .then(data => data.json()) 
      .then(data => { 
       this.setState({ 
        info: data 
       }) 
       console.log(data) 
      },() => { 
       this.setState({ 
       requestFailed: true 
       }) 
      }) 
    } 


    render() { 
     if (!this.state.latLongSubmitted) return <p>Waiting for coordinates...</p> 
     if (this.state.requestFailed) return <p>Failed</p> 
     if (!this.state.info) return <p>Loading...</p> 
     return(
      <div> 
       <h1>The current temperature in {this.state.info.timezone} is: {this.state.info.currently.apparentTemperature}&#8457;.</h1> 
       <h1>The 8 day forecast for {this.state.info.timezone}:</h1> 
       <ul> 
        {this.state.info.daily.data.map((day, id) => 
         <div key={{id}>{day}} id="weatherCard"> 
          <WCard time={this.timeDateConverter(day.time)} 
           high={day.temperatureHigh} 
           low={day.temperatureLow} 
           summary={day.summary} 
           icon={day.icon} 
           humidity={day.humidity} 
           sunrise={this.timeConverter(day.sunriseTime)} 
           sunset={this.timeConverter(day.sunsetTime)} 
           rainProb={day.precipProbability} 
           windspeed={day.windSpeed} 
          /> 
         </div> 
        )} 
       </ul> 

       <a href="https://darksky.net/poweredby/">Powered by DarkSky</a> 
      </div> 
     ) 
    } 
} 
+0

)(componentWillUpdateの内側に、このようにしてみ? –

答えて

1

ITSはLattitudeと経度による()independently.componentWillRecievePropsをとっている場合にのみプロパティが変更と呼ばれます。 latLong変数は、コンポーネントが初めて読み込まれるときにのみ変更されます(componentDidMount())。 あなたが `代わりにあなたの主成分で` componentDidMount`のcomponentDidUpdate`をチェックすることができ

componentWillUpdate(){ 

    if(this.state.latBool === true && this.state.longBool === true) { 
     this.setState({ 
      latLong: this.state.lat + "," + this.state.long 
     }) 

    } 
} 
関連する問題