2016-11-05 70 views
0

我一直在尋找幾天,似乎無法得到這個工作,它讓我瘋了!從父母「一擊」修改孩子狀態

目標是增加「全部展開」/「全部摺疊」按鈕的手風琴。通過將propAll屬性傳遞給子組件,並通過更新componentWillReceiveProps中子組件的展開狀態,我設法讓它在某個時刻起作用,但是如果父組件設置爲在定時器上自動獲取數據,那麼它意味着子狀態被更新以在第二次獲取之後摺疊或展開所有面板,這不是所需的行爲。

class App extends React.Component { 

    constructor(props){ 
    super(props); 
    this.state = { 
     "teams": [{ Name: "Liverpool", Players: ["Lovren", "Coutinho"]}, {Name:"Arsenal", Players: ["Ozil", "Welbeck"]},{Name: "Chelsea", Players: []}], 
     toggleAll: false, 
     toggleText: "Expand All" 
    } 
    } 

    _toggleAll(event){ 
    event.preventDefault(); 
    let text = "Expand All"; 
    if (!this.state.toggleAll === true){ 
     text = "Collapse All" 
    } 
    this.setState({toggleAll: !this.state.toggleAll, toggleText: text}); 
    console.log("toggleAll", this.state.toggleAll); 
    } 


    render() { 
    return (
     <div className="headers"> 
     <button onClick={this._toggleAll.bind(this)}>{this.state.toggleText}</button> 
     {this.state.teams.map((team, index) => 
             <Header className="" key={index} title={team.Name} players={team.Players} /> 
     )} 

     </div> 
    ); 
    } 
} 

class Header extends React.Component { 
    constructor(props){ 
    super(props); 
    this.state = { 
     expanded: false 
    } 
    } 

    componentWillMount(){ 
    console.log(this.props.title); 
    console.log(this.props.players); 
    } 

    _expand(event){ 
    event.preventDefault(); 
    this.setState({expanded: !this.state.expanded}); 
    } 

    render() { 
    let players; 
    if(this.state.expanded) 
    { 
     players= <ul> 
        {this.props.players.map((player, index) => <li key={index}>{player}</li>)} 
       </ul> 
    } 

    return (
     <div> 

     <div className="header" > 
      <p onClick={this._expand.bind(this)}>{this.props.title}</p> 

     </div> 
     {players} 
     </div> 

    ); 
    } 
} 


React.ReactDOM.render(
    <App />, 
    document.getElementById('container') 
); 

小提琴下面提供 https://jsfiddle.net/aamirjaffer/x52bhdq6/

+0

您的頁眉組件不應該有'狀態'。改用道具。 –

回答

0

你需要從在App組件傳遞一個道具給它的「collapseAll」狀態的頭。我更新了頭的呈現在應用程序像這樣:

<Header 
    className = "" 
    key={index} 
    title={team.Name} 
    players = {team.Players} 
    allExpanded={this.state.toggleAll} 
/> 

然後頭組件需要偵聽conponentWillReceiveProps該道具的變化,並相應地設置自己的狀態,像這樣:

componentWillReceiveProps(nextProps) { 
    if (nextProps.allExpanded !== this.props.allExpanded) { 
    this.setState({ expanded: nextProps.allExpanded }); 
    } 
} 

我分叉你的小提琴,這些變化,它一切正常:https://jsfiddle.net/xkp4snmx/

+0

這正是我之前所做的,我原本是這樣做的,但在設置狀態之前沒有做檢查,因此我看到了這種行爲。 Cheers Ben –

+0

Awesome Aamir :-) –

0

你可以存儲每個團隊的崩潰狀態。

this.state = { 
    teams: [ 
    { 
    Name: "Liverpool", 
    Players: ["Lovren", "Coutinho"], 
    collapsed: true 
    }, 
    { 
    Name: "Arsenal", 
    Players: ["Ozil", "Welbeck"], 
    collapsed: true 
    }, 
    { 
    Name: "Chelsea", 
    Players: ["Hazard", "Oscar", "Willian"], 
    collapsed: true 
    } 
    ] 
} 

js fidds

PS:我可能會使得球員名單不管,只是通過CSS隱藏 - 較少的計算,並與CSS,你可以把它整齊的動畫一個真正的手風琴的感覺。

pss:想把它扔在你的空間&縮進讓它更難以閱讀你的代碼= |