2016-11-17 133 views
0

我正在將App組件的自調用函數傳遞給getBgColor函數WeatherForecast組件。這將從子組件WeatherForecast中獲取一個值,並將其傳遞到App組件以更新this.state.appColorClassLoop with componentDidUpdate

* getBgColor函數在componentDidUpdate()之內,它創建一個循環並使瀏覽器崩潰。新的反應,不知道如何解決這個問題。

export default class App extends Component { 
    constructor(props) { 
    super(props); 

    this.state = { appColorClass: 'app-bg1' }; 
    } 

    setAppColor(colorClass) { 
    alert("set className"); 
    this.setState({ appColorClass: colorClass }); 
    } 

    render() { 
    return (
    <div className={"app-container " + this.state.appColorClass}> 
     <div className="main-wrapper"> 

      <WeatherForecast getBgColor={color => this.setAppColor(color)} /> 

     </div> 
    </div> 
    ); 
    } 
} 


class WeatherForecast extends Component { 
    componentDidUpdate() { 
    console.log('Component DID UPDATE!') 
     //The function `setAppColor` from `App` component is passed into `getBgColor` 
     this.props.getBgColor(this.appColor(this.props.weather)); 
    } 

    appColor(weatherData) { 
    console.log("app color working"); 

    let temp = 0; 
    if (typeof weatherData === 'undefined' || weatherData === null) { 
     console.log(" initial Color went through"); 
     return 'app-bg1'; 
    } 
    temp = Math.round(weatherData.list[0].main.temp - 273.15); 
    if (temp <= -30) { 
     return "app-bg1"; 
    } 
    if (temp >= -29 && temp <= -21) { 
     return "app-bg2"; 
    } 
    if (temp >= -20 && temp <= -11) { 
     return "app-bg3"; 
    } 
    if (temp >= -10 && temp <= 4) { 
     return "app-bg4"; 
    } 
    if (temp >= 5 && temp <= 15) { 
     return "app-bg5"; 
    } 
    if (temp >= 16 && temp <= 24) { 
     return "app-bg6"; 
    } 
    if (temp >= 25 && temp <= 32) { 
     return "app-bg7"; 
    } 
    if (temp >= 33 && temp <= 38) { 
     return "app-bg8"; 
    } 
    if (temp >= 39) { 
     return "app-bg9"; 
    } 
    } 

    render() { 

    return (
     <div className="text-center col-xs-12"> 
     <h1 id="temp">{this.displayTemp(this.props.weather)}<sup>&deg;</sup></h1> 
     <h1>{this.displayCity(this.props.weather)}</h1> 
     </div> 
    ); 
    } 
} 
+1

將thisComponentUpdate添加到WeatherForecast,並在this.props.weather === nextProps.weather時返回false。或者取決於你想要做什麼,將getBgColor的調用移動到componentDidMount,以便它只被調用一次。 –

+0

' this.setAppColor(color)} />''可以只是'',不需要附加功能 –

回答

0

我結束了根據shouldComponentUpdate屬性值返回true或false約翰尼Klironomos的建議下去。

* this.props.weather未定義,一旦應用程序加載,因爲用戶需要選擇一個城市來查看其天氣。

shouldComponentUpdate(nextProps) { 
    if(this.props.weather === 'undefined'){ 
     return true 
    } 
    return this.props.weather !== nextProps.weather 
    } 
1

循環是遞歸的,因爲WeatherForecast組件支架後(更新),它調用getBgColor道具,這臺父狀態,這將觸發子更新,這就要求getBgColor ...你得到的圖片。

老實說,我可能會建議移動邏輯一點點...因爲weather作爲道具傳遞,然後顏色傳回來,它似乎更像「反應」喜歡處理在父零件。當數據流向下遊時,跟蹤更簡單。假設您的要求將您引導至此位置,則在setAppColor中添加一個簡單的檢查即可解決問題。

setAppColor(colorClass) { 
    alert("set className"); 
    // only set state if it's changing 
    if (colorClass != this.state.appColorClass) { 
    this.setState({ appColorClass: colorClass }); 
    } 
} 
+0

我試圖避免寫因爲我已經在'WeatherForecast'組件中擁有'app'組件中'state.weather'的另一個mapStateToProps。這更多的是學習經驗/練習,以便學習如何將孩子的財產傳遞給他們的父母。感謝setAppColor中if語句的建議:) –