reactjs为componentsWillReceiveProps重置道具

时间:2017-09-14 20:41:35

标签: 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将state设置为true,这会在div中添加lb-active类,它从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的状态设置为false来关闭div,即nextProps。 showLightbox仍然是真的。因此,如果我关闭它(closeLightbox)并单击我的页面上的其他onClick,它仍然会查看我的组件,看到nextProps.showLightbox仍然设置为TRUE并打开灯箱。

如果特定链接是被点击的链接,我只希望灯箱打开。将showLightbox的状态设置为false的所有其他链接似乎有点过分,所以我猜测我没有正确地看待这个。

由于

3 个答案:

答案 0 :(得分:0)

您可以将closeLightbox方法移至上部组件并从父级管理showLightbox道具。然后,组件DisplayLightbox将包含3个道具:showLightboxtravelCity和方法closeLightbox

将关闭灯箱移至父组件时,不再需要事件componentWillReceiveProps

答案 1 :(得分:0)

  

让所有其他链接设置状态似乎有点过分   showLightbox为false,所以我猜我不是在看这个   正常。

为什么不配置您想打开/关闭灯箱的一个链接呢?

正如我所看到的那样,从父组件或外部组件获得活动状态的组件不应该费心去管理它自己的状态。
您可以在父级状态下管理开/关状态,并将isOnonClose事件处理程序传递给LightBox
单击LightBox后,它将调用向下传递给它的处理程序,并且父级将isOn的状态更改为false,这将触发具有{{1}的新prop的渲染1}}对于isOn这次它的值是LightBox 在点击外部false / link时,父级会听取它并将button的状态更改为isOn,然后true将再次传递给isOn {1}} 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>

答案 2 :(得分: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,我保持隐藏此灯箱按钮,除非this.state.showLightbox为true。当发生这种情况时,按钮会显示,并在单击时切换showLightbox状态,从而删除灯箱和按钮。

不确定这是否是理想的解决方案,但似乎有效。