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



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

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

全局反应组件的一部分

componentDidMount() {
document.addEventListener("onGobalMessage", this.onSnackMessage);
}
componentWillUnmount() {
document.removeEventListener("onGobalMessage", this.onSnackMessage);
}
onSnackMessage = evt => {
const { detail } = evt;
this.setState({ open: true, ...detail });
};

调度程序对象

export const globalMessage = {
success: message => {
let event = new CustomEvent("onGobalMessage", {
detail: {
message,
variant: "success"
}
});
document.dispatchEvent(event);
},
error: message => {
let event = new CustomEvent("onGobalMessage", {
detail: {
message,
variant: "error"
}
});
document.dispatchEvent(event);
}
};

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

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

不。使用事件是一种模式- "观察者模式"。它不是一个反模式,但正如 riotjs 在 v4 中所说的那样,它是:

"[...]一个固执己见的决定,可能不适用于所有用户。

Riot 的灵感来自 act,在现在独立的可观察包中进行了解释:

通过使用可观察量,扩展可以侦听这些事件并对其做出反应。它们扩展内核,以便内核不知道这些模块。这称为"松耦合"。

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

简而言之:如果你的心智模型在document事件中运作良好,那就去做吧!React 使你能够做到这一点。


附言我个人经历的补充:

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

相关内容

最新更新