从组件打开模态

Open a modal from a component

本文关键字:模态 组件      更新时间:2023-09-26

我正在开发一个需要显示和隐藏模态的组件。

这就是我在React 中的渲染方法

    <div style={{visibility : this.state.displayModal}}>
      <p>Pop up: Bet Behind Settings</p>
    </div>
    <button onClick={this._openModal}>CLICK</button>

这是的函数

  _openModal = () => {
    if (this.state.displayModal === 'hidden') {
      this.setState({
        displayModal : 'visible',
      })
    } else {
      this.setState({
        displayModal : 'hidden',
      })
    }
  }

我主要关心的是,如何以更优雅的方式设置状态,或者应该这样做?

这是的完整代码

constructor (props) {
    super(props);
    this.state = {
      displayModal : 'hidden',
    }
  }
  render () {
    return (
      <div style={{visibility : this.state.displayModal}}>
          <p>Pop up: Bet Behind Settings</p>
      </div>
      <button onClick={this._openModal}>CLICK</button>
    )
  }
  _openModal = () => {
    if (this.state.displayModal === 'hidden') {
      this.setState({
        displayModal : 'visible',
      })
    } else {
      this.setState({
        displayModal : 'hidden',
      })
    }
  }

那么,应该如何以React的方式弹出。

我认为这是一个很好的方法。但如果将displayModel设置为布尔值,它会更简洁:

_toggleModal = () => this.setState({displayModal: !this.state.displayModal})

在复杂的页面上使用隐藏将是一个性能问题。不如试试这样的东西;

render() {
  var returnIt;
  if (this.state.hide) {
    returnIt = null;
  } else {
    returnIt = (
      <div style={{visibility : this.state.displayModal}}>
      <p>Pop up: Bet Behind Settings</p>
      </div>
      <button onClick={this._openModal}>CLICK</button>      
    )
  }
  return (returnIt);
}

这只是个人观点,但我认为更好的用户体验是按钮应该只用于打开模态;并且应该通过单击模态中的X(如果有的话)或单击模态之外的任何位置来关闭模态。

也就是说,如果你确实需要按钮在这两种状态之间切换,那么这样的按钮怎么样?

constructor (props) {
    super(props);
    this.state = {
      displayModal : false
    }
  }
  render () {
    return (
      <div style={{visibility : this.state.displayModal === true ? 'visible' : 'hidden'}}>
          <p>Pop up: Bet Behind Settings</p>
      </div>
      <button onClick={this._toggleModal}>CLICK</button>
    )
  }
  _toggleModal = () => {
    const current = this.state.displayModal;
    this.setState({
      displayModal : !current
    }); 
  }

使用https://github.com/fckt/react-layer-stack你可以这样做:

import { Layer, LayerContext } from 'react-layer-stack'
// ... for each `object` in array of `objects`
const modalId = 'DeleteObjectConfirmation' + objects[rowIndex].id
return (
    <Cell {...props}>
        // the layer definition. The content will show up in the LayerStackMountPoint when `show(modalId)` be fired in LayerContext
        <Layer use={[objects[rowIndex], rowIndex]} id={modalId}> {({
            hideMe, // alias for `hide(modalId)`
            index } // useful to know to set zIndex, for example
            , e) => // access to the arguments (click event data in this example)
          <Modal onClick={ hideMe } zIndex={(index + 1) * 1000}>
            <ConfirmationDialog
              title={ 'Delete' }
              message={ "You're about to delete to " + '"' + objects[rowIndex].name + '"' }
              confirmButton={ <Button type="primary">DELETE</Button> }
              onConfirm={ this.handleDeleteObject.bind(this, objects[rowIndex].name, hideMe) } // hide after confirmation
              close={ hideMe } />
          </Modal> }
        </Layer>
        // this is the toggle for Layer with `id === modalId` can be defined everywhere in the components tree
        <LayerContext id={ modalId }> {({showMe}) => // showMe is alias for `show(modalId)`
          <div style={styles.iconOverlay} onClick={ (e) => showMe(e) }> // additional arguments can be passed (like event)
            <Icon type="trash" />
          </div> }
        </LayerContext>
    </Cell>)
// ...