【问题标题】:Clean way to implement messagebox pattern in react在反应中实现消息框模式的干净方法
【发布时间】:2019-02-23 22:02:39
【问题描述】:

有没有一种干净的方法来实现这样的反应中的消息框模式?

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);
      }

    }

如果不求助于 refs、违反 promise 规则(进行延迟)或做 DOM 诡计(使用渲染组件的包装器),似乎没有办法解决这个问题。

我构建了一个遵循我上面的 API 的组件,除了回调,但它需要一个 ref 并且感觉我没有以反应的方式构建东西。

【问题讨论】:

  • 你的代码到底有什么问题?
  • @dfsq - 没有问题。该代码是我想编写的 MessageBox api 的一个示例,它不使用 refs、deferreds 或开箱即用的 dom 操作。我觉得我在重复我原来的帖子,你读了吗?
  • 您尝试过使用门户网站吗? reactjs.org/docs/portals.html,我大部分时间都倾向于使用它

标签: reactjs design-patterns


【解决方案1】:

您可以在MyComponent 中呈现一个消息框。使用fixed 定位,没有人可以看到该框在文档树中的哪个位置被定义。这样,您就可以避免节点引用或像 Redux 这样的全局状态机制。

您可以将点击处理程序作为道具提供给MessageBox,但在MessageBox 组件中提供buttons 渲染道具 可能会更好,如下所示。这样,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

【讨论】:

  • 谢谢我尝试了那个模式,但它需要从另一个事件触发,请参阅我的 onDeleteButtonClick。用户确认删除确定后,我想使用数据参数进行删除。如果不使其成为实例变量,我将如何坚持下去?我试图让它像 window.confirm 一样工作
  • @user210757 这很简单。 :) 见我新添加的onDeleteButtonClick
  • 我非常喜欢这个,我正在尝试理解渲染道具。新的反应,如果你没有注意到!
  • 谢谢,这太棒了,正是我想要的。学到了一些东西 - 渲染道具,并将 jsx 元素作为数组传递,因此您不必包装包含元素(按钮)。在我的情况下,我没有在渲染函数上使用 Button 参数,我并没有真正明白这一点。我在 MyComponent 中导入一个 react-bootstrap 按钮并在那里使用它
  • 很高兴听到这个消息!当您想从消息框向消息框用户提供自定义按钮元素时,可以使用Button 参数,以便按钮的呈现完全由消息框组件控制。这种渲染和功能的分离是渲染道具的关键,但如果你在整个应用程序中使用相同的按钮,那么这当然没关系。
【解决方案2】:

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

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

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

作为 MessageModal 的 reducer 状态

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

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

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

【讨论】:

  • 感谢您的建议。我确实连接了 redux,但想保持简单。让我看看上下文
  • 我认为redux可能是正确的选择。如果你做对了,它就简单明了。为什么你认为它很复杂?
  • 我只是不想为此需要 redux,我希望它是一个独立的解决方案,可以在没有 redux 的项目中使用。
猜你喜欢
  • 2010-09-09
  • 2022-01-03
  • 1970-01-01
  • 2010-10-16
  • 2011-11-02
  • 2014-03-07
  • 2010-12-01
  • 2011-03-12
  • 1970-01-01
相关资源
最近更新 更多