2017-09-14 36 views
3

我的第一個反應項目的第一個問題。reactjs重置組件的道具將接收作業

我想弄清楚如何在特定的onClick鏈接上最好地實現組件,以便能夠重新觸發此效應並且不會受到頁面上其他鏈接的影響。前兩個問題正在工作,但我似乎沒有其他鏈接不影響組件。

我有一個DisplayLightbox組件我的網頁接受一對夫婦值

<div> 
    <DisplayLightbox 
    showLightbox = {this.state.showLightbox} 
    lightboxValue = {this.state.travelCity} 
    /> 
</div> 

我想觸發燈箱被調用設置狀態(和發送道具)的功能鏈接。這部分似乎工作正常。

onClick={() => this.showLightbox(el.field_city)} 

showLightbox(travelCity){ 
    this.setState({ 
    showLightbox: true, 
    travelCity: travelCity, 
    }); 
} 

以我DisplayLightbox部件,所述componentWillReceiveProps確實設置狀態爲真,這增加了磅活性類在div,其中,從所述的CSS,顯示在燈箱的div。這看起來很好。

class DisplayLightbox extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
    showLightbox: false, 
    }; 
    } 

    componentWillReceiveProps(nextProps) { 
    if (nextProps.showLightbox !== this.state.showLightbox) { 
     this.setState({ showLightbox: nextProps.showLightbox }); 
    } 
    } 

    closeLightbox() { 
    this.setState({ 
     showLightbox: false, 
    }); 
    } 

    render() { 
    var lbActive = (this.state.showLightbox === true) ? "lb-active" : "" 
    return <div className={"lightbox " + lbActive }> 
    <div className={"lightbox-close " + lbActive } onClick={() => 
    this.closeLightbox()}>CLOSE</div> 
    Copy in lightbox 
    </div>; 
    } 
} 

尋找到它,我看到的是,由於道具不是由組件控制和只讀,一旦它被設置爲True,並且我通過設置showLighbox的狀態恢復到假,nextProps關閉股利。 showLightbox保持真實。所以,如果我關閉它(closeLightbox)並單擊我的頁面上的其他onClick,它仍會查看我的組件,看到nextProps.showLightbox仍設置爲TRUE並打開Lightbox。

我只想讓燈箱打開,如果該特定鏈接是被點擊的人。看起來每個其他鏈接都將showLightbox的狀態設置爲false,所以我猜測我沒有正確地看待它。

感謝

回答

0

你可以只動closeLightbox方法上部件和管理父showLightbox道具。然後組件DisplayLightbox將具有3個道具:showLightboxtravelCity和方法closeLightbox

當您將Lightbox關閉到父組件時,不再需要事件componentWillReceiveProps

+0

非常感謝您的快速回復。我已經添加了一個按鈕div來切換showLightbox狀態,並且正如您所說,我可以從子項中移除componentWillReceiveProps。似乎工作。 – user1932694

0

這似乎矯枉過正有所有其他環節 showLightbox的狀態設置爲false,所以我猜我不是在尋找這個 正常。

爲什麼不配置一個你想打開/關閉燈箱的鏈接呢?

就像我看到的那樣,從父級或外部組件獲取其活動狀態的組件不應該打算在自己的狀態下進行管理。
您可以管理父級狀態中的開/關狀態,並將isOnonClose事件處理程序傳遞到LightBox
一旦LightBox被點擊它會調用句柄向下傳遞給它和家長會的isOn狀態改變爲false,這將觸發與該LightBox這一次它的價值是falseisOn新道具渲染。
同時單擊外部link/button家長會聽,並改變isOn的狀態true,並再次isOn將向下傳遞給LightBox與它的true閃亮的新價值。

小例子:

const cities = ["ny", "tlv", "ark"]; 
 

 
class Button extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.onClick = this.onClick.bind(this); 
 
    } 
 

 
    onClick() { 
 
    const { item, onClick } = this.props; 
 
    onClick(item); 
 
    } 
 

 
    render() { 
 
    return <button onClick={this.onClick}>{this.props.children}</button>; 
 
    } 
 
} 
 

 
class LightBox extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.onClick = this.onClick.bind(this); 
 
    } 
 

 
    onClick() { 
 
    const { city, onClick } = this.props; 
 
    onClick(city); 
 
    } 
 

 
    render() { 
 
    const { isOn } = this.props; 
 
    const css = `lightBoxStyle ${isOn && "onStyle"}`; 
 
    return (
 
     <div 
 
     className={css} 
 
     onClick={this.onClick}> 
 
     | 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
class App extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.state = { 
 
     turnedOn: [] 
 
    }; 
 

 
    this.on = this.on.bind(this); 
 
    this.off = this.off.bind(this); 
 
    } 
 

 
    on(city) { 
 
    const { turnedOn } = this.state; 
 
    if (turnedOn.find(c => c === city)) { 
 
     return; 
 
    } 
 
    const nextState = [...turnedOn, city]; 
 
    this.setState({ turnedOn: nextState }); 
 
    } 
 

 
    off(city) { 
 
    const nextState = this.state.turnedOn.filter(c => c !== city); 
 
    this.setState({ turnedOn: nextState }); 
 
    } 
 

 
    render() { 
 
    const { turnedOn } = this.state; 
 
    return (
 
     <div> 
 
     {cities.map((city, i) => { 
 
      const isOn = turnedOn && turnedOn.includes(city); 
 

 
      return (
 
      <div style={{ display: "inline-block", margin: "0 10px" }}> 
 
       <LightBox city={city} isOn={isOn} onClick={this.on} /> 
 
       <hr /> 
 
       <Button item={city} onClick={this.off}> 
 
       Close the light! 
 
       </Button> 
 
      </div> 
 
     ); 
 
     })} 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
ReactDOM.render(<App />, document.getElementById("root"));
.lightBoxStyle{ 
 
    border: 1px solid #eee; 
 
    width: 30px; 
 
    height: 30px; 
 
    text-align: center; 
 
    box-shadow: 0 0 4px 1px #222; 
 
    border-radius: 50%; 
 
    margin: 0 auto; 
 
    cursor: pointer; 
 
} 
 

 
.onStyle{ 
 
    background-color: #333; 
 
    color: #fff; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="root"></div>

+0

這太棒了!我用你的按鈕的想法,雖然作爲一個隱藏的div,只有當showLightbox爲真時才顯示。另外,「從父級或外部組件獲取其活動狀態的組件,不應該費心去管理它在自己的狀態」,這是非常有用的。雖然,在類DisplayLightbox中,這將是我添加功能的地方(我相信)。 – user1932694

+0

事實上,你可以在'LightBox'內管理一個狀態,但它應該是一個只關心'LightBox'的狀態。請記住,在_Matrix_電影中,「Neo」沒有決定成爲選擇的人,外力決定了他對他的影響:) –

+0

@ user1932694順便說一句,如果你認爲這有幫助,你可以upvote答案,如果答案爲您提供了一個解決方案,那麼您應該接受它,以便將您的問題標記爲已回答。 –

0

基於偉大的答覆,我把收出的孩子,回到父。 我這樣做是通過增加一個收藏夾按鈕DIV父

 <div className={"lightbox-button " + this.state.showLightbox} onClick={() => this.showLightbox()}></div> 

     <DisplayLightbox 
     showLightbox = {this.state.showLightbox} 
     lightboxValue = {this.state.travelCity} /> 

這需要同樣的功能showLightbox,我稍微修改切換

showLightbox(travelCity){ 
this.setState({ 
    showLightbox: !this.state.showLightbox, 
    travelCity: travelCity, 
}); 

}

用css,我保持這個lightbox-button隱藏,除非this.state.showLightbox爲true。發生這種情況時,會顯示按鈕,點擊時切換showLightbox狀態,從而刪除lightbox和按鈕。

不知道這是否是理想的解決方案,但它似乎工作。