2017-11-07 9 views
2

ReactJS 구성 요소를 작성할 때 자식 구성 요소가 잠시 동안 상태를 잃어 버리는 것을 발견했습니다. 자식 구성 요소가 다른 렌더링 함수로 렌더링되면 발생합니다.ReactJS 자식 구성 요소가 다른 함수로 렌더링 될 때 상태가 손실 됨

부모 구성 요소는 신체의 하위 구성 요소를 렌더링 또는 헤더 중 어느 하나 때문에 다양한 조건에 2 서브 렌더링 기능을 가지며. somethingHappens는 그것이 ChildComponent을 렌더링하는 다른 렌더링 함수를 사용하는 것을 의미

... 

    renderInHeader =() => (<Header><ChildComponent /></Header>); 

    renderInBody =() => (<Body><ChildComponent /><Body>); 

    render =() => { 
     if (somethingHappens) { 
     return this.renderInHeader(); 
     } 
     return this.renderInBody(); 
    } 

    ... 

.

그러면 ChildComponent은 상태를 잃게됩니다. (아이 컴퍼넌트 상태가 리 셋트됩니다). 나는 그런 일이 왜 이해


, 나는 실제로 아이의 상태가 더 자주 재설정되지 않는 약간 놀랐어요 (즉 재설정 할 때마다 부모 노드를 다시 렌더링).

그러나 이상적인 해결책은 무엇입니까?

  • 하위 구성 요소에서 상태를 사용하지 마십시오? (안전성이 보장되지 않았기 때문에)

  • key=을 ChildComponent에 지정하면 다시 렌더링하는 동안 독립 노드로 처리 될 수 있습니까? (key이 매퍼 외부에서 작동하는지 확실하지 않음)

  • ref을 사용 하시겠습니까? (그런 식으로 작동하는지 전혀 모른다)

  • 반응 16에서 새로운 "Portal"을 사용 하시겠습니까? 내가 HeaderBody에 대한 변수를 사용할 수 있습니다 알고, 그래서 하나의 기능이 필요한 렌더링있다 :


주 (아직 시도하지 않은). 그러나 실제 사례는 더 복잡 할 수 있으며 여러 영역에 여러 하위 구성 요소가 분산되어있을 수 있습니다. 여기 즉

 ... 

    renderInBody =() => (
     <Body> 
      <Header> 
       <ChildComponent1 /> 
       <ChildComponent2 /> 
      </Header> 
      <ChildComponent3 /> 
     </Body> 
    ); 

    renderInHeader =() => (
     <Header> 
      <ChildComponent3 /> 
      <ChildComponent1 /> 
      <Body> 
       <ChildComponent2 /> 
      </Body> 
     </Header> 
    ); 

    render =() => { 
     if (somethingHappens) { 
     return this.renderInHeader(); 
     } 
     return this.renderInBody(); 
    } 

    ... 

, 아이 컴포넌트 1,2,3 정말 변경되지 않습니다, 단지 자신의 위치와 부모의 구조가 변경됩니다.

그리고 하위 구성 요소 위치 지정 전략을 HeaderBody 구성 요소에 넣는 것이 좋은 해결책이라고 생각하지 않습니다.

ChildComponent의 상태를 유지할 수 있습니까?

+0

하위 구성 요소의 상태를 유지 관리 하시겠습니까? –

답변

0

ChildComponent은 항상 렌더링되므로 if-else 블록의 일부가 아니어야합니다.

render =() => { 
    const ParentComponent = somethingHappens ? Header : Body; 
    return (
    <ParentComponent> 
     <ChildComponent /> 
    </ParentComponent> 
); 
}; 
+0

나는 그것에 대해 생각했다. 마지막 "노트"섹션에서 그것에 대해 이야기했습니다. 즉, 가능한 여러 개의 상위 구성 요소에 무작위로 배포되는 여러 하위 구성 요소가있을 수 있습니다. 이 솔루션은 그렇게 잘 작동하지 않습니다. –

+0

실제 사례 (ChildComponent의 실제 상태가 이렇게 ..로 제공됨)를 제공하면 우리는 당신에게 멋진 해결책을 제공 할 것입니다. –

0

매번 ChildComponent의 새 인스턴스를 만드는 것이 더 좋습니다.

let alwaysNewChildComp = <ChildComponent /> 

renderInHeader =() => (<Header>{alwaysNewChildComp}</Header>); 

renderInBody =() => (<Body>{alwaysNewChildComp}<Body>); 

또는

let alwaysNewChildComp = React.createClass({ 

     render: function() { 
     return (<div><ChildComponent /></div>) 
     } 
}) 

renderInHeader =() => (<Header>{alwaysNewChildComp}</Header>); 

renderInBody =() => (<Body>{alwaysNewChildComp}<Body>); 

그것은 당신의 ChildComponent 상태를 재설정합니다.

redux과 더 이상 갈 수 있습니다.

+0

나는 redux를 많이 사용했다. 실제로는 너무 많이 (redux가 원래 설계된 것처럼). 일부 소규모 프로젝트의 경우 약간의 규모 축소를 시도하고 재사용 가능한 구성 요소로 멍청한 구성 요소를 만듭니다. 이것이 내가이 상태에 대한 신뢰성 문제를 겪고있는 이유입니다. –

0

하위 구성 요소의 변수를 정의하고이를 사용하여 상위 구성 요소의 렌더링 순서를 지정할 수 있습니다. 그래서 예제 코드는

renderInBody = (child1,child2,child3) => (
    <Body> 
     <Header> 
      {child1} 
      {child2} 
     </Header> 
     {child3} 
    </Body> 
); 

renderInHeader = (child1,child2,child3) => (
    <Header> 
     {child3} 
     {child1} 
     <Body> 
      {child2} 
     </Body> 
    </Header> 
); 

render =() => { 
    let child1=<ChildComponent key={1}/>; 
    let child2=<ChildComponent key={2}/>; 
    let child3=<ChildComponent key={3}/>; 
     if (somethingHappens) { 
     return this.renderInHeader(child1,child2,child3); 
     } 
     return this.renderInBody(child1,child2,child2); 
} 

그들이 상태를 유지할 수 있도록 자녀의 구성 요소가 고유 키가 있는지 확인 될 것입니다.

+0

고맙습니다, 아마도 가장 좋은 답변 일 것입니다 만,'key'가 루프 외부에서 작동한다는 것을 알지 못했지만, 소스를 확인하고 나중에 살펴볼 것입니다. –