2017-09-14 52 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和按钮。

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