2016-08-21 1 views
0

단일 저장소의 현재 상태를 기반으로 라우팅하는 간단한 라우터를 만들었습니다. 라우터는 각 하위 노드를보고 상태를 추출하고 select ed를 찾은 다음 해당 경로가 when 속성에 따라 표시되어야하는지 테스트합니다.단순한 저장소 기반 라우터에서 불필요한 재 렌더링

var Router = React.createClass({ 
    render: function() { 
    const {children, state} = this.props; 
    const activeRoute = React.Children.toArray(children).find(when); 

    return React.createElement(
     activeRoute.props.component, 
     Object.assign(
     {}, 
     activeRoute.props.select(state), 
     { 
      setState: this.props.setState, 
     } 
    ) 
    ); 

    function when(child) { 
     return child.props.when(child.props.select(state)); 
    } 
    } 
}); 

var Route = React.createClass({ 
    getDefaultProps: function() { 
    return { 
     select: identity, 
     when: alwaysTrue, 
    } 
    }, 

    render: function() { 
    throw new Error('Route should never render'); 
    }, 
}); 

이러한 구성 요소는 이와 같이 사용할 수 있습니다.

<Router state={this.state} setState={this.sState}> 
    <Route component={Pets} when={this.onPets} select={this.selectPets} /> 
    <Route component={Home} /> 
</Router> 

why-did-you-update를 사용하여, I는 불필요하게 다시 렌더링되는 것을 발견했다. 이러한 불필요한 재 렌더링을 제거하고 싶지만 그렇게하지 못하고 있습니다. 무엇이 재 렌더링을 유발하고 어떻게 피할 수 있습니까?

실무 데모 here이 있습니다. "애완 동물보기 (여기를 클릭하십시오)"를 클릭하면 콘솔에서 피할 수있는 일련의 재 렌더링 경고를 끕니다.

답변

0

두 렌더링 간의 children 속성이 동일하지만 동일한 참조가 아니기 때문에 why-did-you-update이 우리에게 경고하는 것으로 나타났습니다. 이는 각 렌더마다 새 React.createElement을 반환하기 때문에 발생합니다.

이 문제를 해결하려면 childrenthis.props, this.state, app 또는 전체적으로 이동할 수 있습니다. createClass 대신 es6 클래스를 사용하는 경우 인스턴스 변수를 만들 수 있습니다. 이 메서드 중 하나를 사용하여 render 메서드에 children을 전달할 수 있습니다.

<Router state={this.state} setState={this.sState} children={routes} /> 

실시 예는 here이다.

관련 문제