在React中实现消息框模式的干净方法

时间:2019-02-22 21:54:59

标签: reactjs design-patterns

是否有一种干净的方法来以这种方式实现消息框模式?

import MessageBox from "MessageBox";

class MyComponent {
    render () {...}
    onDeleteButtonClick = async (data) => {

      let result = await  MessageBox.show("Delete?", "Sure you want to delete   this?", MessageBox.Buttons.OkCancel);

      if(result === MessageBox.Result.Ok) {
        deleteThing(data);
      }

    }

似乎没有办法不依靠引用,违反承诺规则(延期)或进行DOM欺骗(具有包装组件的包装器)。

我建立了一个遵循上述API的组件,除了有一个回调,但它需要一个ref并觉得我不是在以响应的方式构建事物。

2 个答案:

答案 0 :(得分:1)

我几乎总是看到使用redux实现此模式,我将以这种方式进行解释,因为我认为这是社区中选择最多的方法。

您可以使用redux来实现一个消息框。您在应用程序源处实例化消息框组件 App.js

<div>
  <Main />
  <MessageModal />
</div>

处于MessageModal的还原程序状态

{
open: true|false,
props: {}|{...}
}

然后,您只需导入消息框的打开/关闭操作并在需要的地方使用它(Components / Sagas)

其他选项可能正在使用react’s context

答案 1 :(得分:1)

您可以在MyComponent内显示一个消息框。使用fixed定位时,没人会看到框在文档树中的定义位置。这样,您就可以避免节点引用或Redux之类的全局状态机制。

您可以将点击处理程序作为道具提供给MessageBox,但在buttons组件中提供MessageBox render prop 可能会更好。 ,如下所示。这样,MessageBox可以完全控制渲染,MyComponent可以完全控制功能。

import MessageBox from './MessageBox'

class MyComponent extends React.Component {
  onDeleteButtonClick(data) => {
    this.setState({ data, messageBoxOpen: true })
  }

  onMessageOkClick() => {
    deleteThing(this.state.data)
    this.setState({ messageBoxOpen: false })
  }

  render() {
    return (
      // ...content...
      <button onClick={this.onDeleteButtonClick}>delete</button>
      // more content
      <MessageBox
        open={this.state.messageBoxOpen}
        text="Question?"
        buttons={(Button) => [
          <Button text="Ok" onClick={this.onMessageOkClick} />,
          <Button text="Cancel" onClick={this.setState({ messageBoxOpen: false })} />
        ]}
      />
    )
  }
}

// MessageBox.jsx

const Button = ({ text, onClick }) => { /* ... */ }

const MessageBox = ({ open, text, buttons }) => open ? (
  <div>
    {text}
    {buttons(Button)}
  </div>
) : null