我想开发一个带有TypeScript的React App,它可以存储和发送MQTT数据。
有很多(数百个)MQTT 消息,例如:config.laser.enable == "true"
、config.system.value == "23"
或config.user.password == "foobar"
。
所以我最终得到一个对象,比如:
{
"config.laser.enable": true,
"config.system.value": 23,
"config.user.password": "foobar",
...
}
我的每个视觉组件将仅使用这些主题的一小部分。
我的第一个方法是为每个组件创建一个 MQTT 客户端并订阅它们各自的主题,但这似乎有很多开销。所以我认为最好只有一个 MQTT 客户端,它订阅所有内容并以全局状态存储消息数据。 所以我的问题是:我如何(或不应该?)在 React 的全局状态下存储复杂数据(对象),并确保只有组件在全局状态的特定子集发生变化时重新绘制。我可以为此使用React Redux吗?
你能给我举个如何做到这一点的例子吗?
我是 React 的新手,所以如果这是微不足道的,请原谅。
React 上下文应该非常适合此类任务。它也是 Redux 库的主干。 以下是 React 手册的摘录:
上下文旨在共享可以被视为 React 组件树的"全局"数据
使用 React 上下文的概念验证示例:
const GlobalMessages = React.createContext({});
function App() {
return (
<GlobalMessages.Provider value={/* pass the messages here */}>
<SomeComponent/>
<RandomContainer/>
</GlobalMessages.Provider>;
)
}
function SomeComponent() {
// All instances of SomeComponent nested at any level inside
// GlobalMessages.Provider will now have access to its value.
let msgContext = useContext(GlobalMessages);
let message = msgContext.messageTypeA; // Your "selector"
return <Textbox value={message} />;
}
请注意,在上面的示例中,当value
GlobalMessages.Provider
属性更改时,所有使用 上下文的组件都将重新呈现,这可能会对性能产生一些影响。
幸运的是,由于虚拟 DOM 的原因,React 组件重新渲染通常非常便宜。这意味着大多数渲染永远不会触及真正的 DOM。如果您确定有一个昂贵的组件,并且希望避免重新渲染 - 您可以像这样记住它:
function SomeComponent() {
let msgContext = useContext(GlobalMessages);
let message = msgContext.messageTypeA; // Your "selector"
return useMemo(() => {
// The rest of your rendering logic
return <ExpensiveComponent value={message} />;
}, [message])
}