2016-11-17 137 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语句的建议:) –