在 React 全局组件(例如 AppRoot 中的小吃栏)中使用 CustomEvent 是一个坏主意吗?

Ben*_*nce 2 javascript events reactjs

需要一个全局的snackbar通知处理程序,可以从任何地方触发,而不仅仅是反应组件。

我的想法是制作一个监听CustomEvent并仅显示snackbar事件触发时间的组件。我制作了一个简单的事件调度程序类,可以在项目的每个部分中导入。它运作良好并且非常易于使用。

全局 React 组件的一部分

componentDidMount() {
  document.addEventListener("onGobalMessage", this.onSnackMessage);
}

componentWillUnmount() {
  document.removeEventListener("onGobalMessage", this.onSnackMessage);
}

onSnackMessage = evt => {
  const { detail } = evt;
  this.setState({ open: true, ...detail });
};
Run Code Online (Sandbox Code Playgroud)

调度程序对象

componentDidMount() {
  document.addEventListener("onGobalMessage", this.onSnackMessage);
}

componentWillUnmount() {
  document.removeEventListener("onGobalMessage", this.onSnackMessage);
}

onSnackMessage = evt => {
  const { detail } = evt;
  this.setState({ open: true, ...detail });
};
Run Code Online (Sandbox Code Playgroud)

我的问题是:在react项目中使用这种方式是邪恶的吗?:)

Bre*_*222 5

\n

在react项目中使用这种方式是邪恶的吗?

\n
\n\n

不。使用事件是一种模式——“观察者模式”。它不是Antipattern,但正如riotjs 在 v4 中所述,它是:

\n\n
\n

“[\xe2\x80\xa6] 一个固执己见的决定,可能并不适合所有用户。”

\n
\n\n

Riot 的灵感来自于 React,并且位于现在独立的observable-package中中进行了解释:

\n\n
\n

通过使用可观察的,扩展可以侦听这些事件并对它们做出反应。它们扩展了核心,使得核心不知道这些模块。这称为“松耦合”。

\n
\n\n

虽然反应开发人员建议组件对状态变化做出反应(反应式),但他们将最终决定留给用户“您可以根据需要使用尽可能少或尽可能多的 React”

\n\n

简而言之:如果你的心理模型能够很好地处理以下事件document,那就去做吧!React 使您能够做到这一点。

\n\n
\n\n

PS根据我的个人经验补充:

\n\n
    \n
  • 仅使用内部状态的 React 方式,向下传递 props/向上回调并将组件连接到 redux 也会导致一些混乱的代码库。“功能性”和“反应性”并不是干净代码的秘诀。
  • \n
  • 使用事件时,一个陷阱是事件名称不唯一。您可以通过在它们前面加上 js-module-name 前缀,或者从一个文件导入字符串常量来解决这个问题,例如import { ON_GLOBAL_MESSAGE } from src/events.js
  • \n
  • 你可能想要使用钩子来取消/订阅
  • \n
\n\n
import React, { useEffect } from \'react\';\n\nexport const MyComponent = () => {\n  const onSnackMessage = (event) => {\xe2\x80\xa6}\n\n  useEffect(() => {\n    document.addEventListener("onGobalMessage", onSnackMessage);\n    return () => {\n      // Clean up the subscription\n      document.removeEventListener("onGobalMessage", onSnackMessage);\n    };\n  });\n\n\xe2\x80\xa6\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n