2016-01-22 32 views
0

我需要一個父組件來知道它的子組件何時從摺疊狀態變爲展開狀態並反之亦然。與父組件通信而不使用狀態/道具

我不想保持在應用程序狀態(Redux)。我無法將邏輯移至父組件。

我的組成部分是:

  • 我有組分C它是可以擴展的項目/摺疊。
  • 然後,我有組件B,它是組件C在特定情況下的包裝(​​給它可拖動的行爲)。
  • 最後,組件A在循環中列出組件C. A有時把B包裝在B中,有時不包括(當物品不可拖動時)。

我需要B知道C是擴展的,以便擴展時不可拖動。

我不能把展開/摺疊的邏輯放在B中,因爲C應該總是可摺疊/可展開,而不管可否拖動。

是否有任何簡單的方法可以實現這一點,而無需在應用程序狀態下展開/摺疊每個項目的狀態?

我看了一下https://facebook.github.io/react/docs/context.html但在實驗階段似乎還是......

+0

你能解釋一下爲什麼好,你不想「養在應用程序狀態」?爲什麼你需要一個組件B?你可以使用道具進行條件渲染而不需要額外的組件。 –

+0

如果您不想使用狀態,您可能會對React產生錯誤想法:https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#components-are-just-state應用程序狀態 –

+0

我的意思是Redux。我正在使用REDX來保持整個應用程序的狀態,但保持展開/摺疊狀態可以並且應該在組件級別完成,這正是我現在所做的。這就是爲什麼我需要以某種方式將此信息發送到其父組件 – mezod

回答

1

您可以將展開狀態保留在C組件中,並使用通過C組件的道具傳遞的回調來更新B組件的可拖動狀態。 通過這種方式,兩個組件都保持其自己的狀態,不需要在A組件或App狀態(Redux之一)上添加狀態。

下面是一個例子https://jsfiddle.net/snahedis/69z2wepo/28567/

var sampleList = [{id: 1, draggable: true},{id: 2, draggable: false}]; 

var Acomponent = React.createClass({ 
    render: function() { 
    return (
     <div> 
     {sampleList.map(function(component) { 
      if (component.draggable) { 
      return <Bcomponent key={component.id} />; 
      } else { 
      return <Ccomponent key={component.id} />; 
      } 
     })} 
     </div> 
    ); 
    } 
}); 

var Bcomponent = React.createClass({ 
    getInitialState: function() { 
    return { 
     draggable: true 
    } 
    }, 
    hasBeenToggled: function() { 
    this.setState({ 
     draggable: !this.state.draggable 
    }); 
    }, 
    render: function() { 
    return <Ccomponent draggable={this.state.draggable} toggleExpandableCallback={this.hasBeenToggled} />; 
    } 
}); 

var Ccomponent = React.createClass({ 
    getInitialState: function() { 
    return { 
     expanded: false 
    } 
    }, 
    toggleExpandable: function() { 
    this.setState({ 
     expanded: !this.state.expanded 
    }); 

    if (typeof this.props.toggleExpandableCallback === "function") { 
     this.props.toggleExpandableCallback(); 
    } 
    }, 
    render: function() { 
    return (
     <div> 
     <div>I'm the C component and my expanded state is : {this.state.expanded.toString()}</div> 
     <div>{(this.props.draggable) ? "oh, and I'm draggable !" : "and I'm saddly not draggable"}</div> 
     <button onClick={this.toggleExpandable}>Change expandable state</button> 
     </div> 
    ); 
    } 
}); 

ReactDOM.render(
    <Acomponent />, 
    document.getElementById('container') 
); 
+0

是的,這就是我結束了這樣做,謝謝你的答案:) – mezod

0

幾個想法:

1)你總是可以呈現B(A呈現B的,每一個包裝了C),但只需在B中禁用可拖動的行爲時,它不應該可拖動(將其傳遞給B中的isDraggable)。然後,C的可摺疊狀態可以存儲在B中,並將一個道具傳遞給C,因爲B總是在那裏。

2)你可以把所有的狀態A(不知道這是你的「應用程序狀態」)

很難不知道更多的上下文暗示的意思。但是在這種情況下,幾乎有一種更好的方式來分解組件/應用程序狀態,以免它感覺「錯誤」。

+0

感謝您的回答,我認爲讓A始終呈現B,但它是在這種情況下不是一個很好的解決方案。 A有viewmode之間的選擇狀態,viewmode基本上是循環打印C或B(C)。 B向C添加了幾個特性,不僅可拖動,而且還可以在其周圍添加DOM元素,並且它不會真正實現;(要在A中擴展/摺疊信息,我需要某種數組來映射所有項目這是沒有意義的,在這種情況下,將它放在應用程序狀態中會更有意義,應用程序狀態是指Redux,我將再次考慮我的組件結構,謝謝! – mezod

相關問題