2016-11-17 3 views
0

App 컴포넌트에서 getBgColor 함수로 호출하는 자체 함수를 WeatherForecast 컴포넌트로 전달합니다. 이것은 하위 구성 요소 WeatherForecast의 값을 잡고 App 구성 요소에 전달하여 this.state.appColorClass을 업데이트합니다.loop with componentDidUpdate

* getBgColor 기능이 내부에 있습니다. componentDidUpdate() 루프를 생성하고 브라우저를 중단합니다. 새로 반응하고 이것을 해결하는 방법을 모릅니다. WeatherForecast 구성 요소 마운트 후 (업데이트)이이 getBgColor를 호출하는 자식 업데이트를 트리거 부모의 상태를 설정하는 getBgColor 소품을 호출 ... 당신이 사진을 얻을 수 있기 때문에

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

WeatherForecast에 shouldComponentUpdate를 추가하고 this.props.weather === nextProps.weather가 있으면 false를 반환합니다. 또는 무엇을하려고하는지에 따라 getBgColor의 호출을 componentDidMount로 이동하여 한 번만 호출되도록합니다. –

+0

' this.setAppColor (color)} />'는 단지 '이 될 수 있습니다. 추가 기능이 필요하지 않습니다. –

답변

0

나는 shouldComponentUpdate의 속성 값에 따라 참 또는 거짓 반환 조니 Klironomos의 제안에가는 끝났다.

* this.props.weather은 사용자가 날씨를보기 위해 도시를 선택해야하기 때문에 앱이로드되면 정의되지 않습니다.

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

루프는 재귀입니다.

솔직히 말해서 논리를 약간 옮기는 것이 좋습니다 ... 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 문에 대한 제안에 감사드립니다. :) –