React-在分离的React应用程序之间共享状态可能吗



我写了一个React应用程序,现在我想实现一些Tab导航。

问题是,我的react应用程序集成在一个使用Twig模板的Symfony项目中。因此,我的React应用程序位于templates/dashboard/index.html.titch:中

{% block content %}
<div id="react-app"></div>
{% endblock %}

选项卡菜单位于templates/navigation/navbar.html.trick:中

<div class="flex-1 px-4 flex justify-between">
<div id="react-tabs"></div>
</div>

react App.js渲染这两个应用程序。

import React from 'react';
import {render} from 'react-dom';
import {ready} from '../../helper/vanilla-helper'
import ReactTabs from "./ReactTabs";
function ReactApp() {
return (
<div className="App p-20 bg-blue-300">
Blubber
</div>
);
}
export default ReactApp;
ready(() => {
render(
<ReactApp/>,
document.getElementById('react-app')
);
render(
<ReactTabs/>,
document.getElementById('react-tabs')
);
});

我在互联网上做了很多关于共享状态的研究。但这一切似乎只与ONEReactJs应用程序内部及其组件之间的共享状态有关。

在我的情况下,我需要在两个应用程序之间共享状态。这可能吗?还是我应该采取完全不同的方法?

您可以创建一个简单的存储(如在状态管理中(来在组件之间共享状态。如果你需要一个更严肃的解决方案,我建议你应该研究Redux/MobX或其他一些状态管理工具。

在代码段中,只有一个非常基本的计数器是共享的——这样更容易完成:

const { useState, useEffect, useMemo } = React
// observer pattern
const makeObservable = (target) => {
let listeners = []
let value = target

function get() {
return value
}

function set(newValue) {
if (value === newValue) return
value = newValue
listeners.forEach((l) => l(value))
}

function subscribe(listenerFunc) {
listeners.push(listenerFunc)
return () => unsubscribe(listenerFunc) // can be used in the useEffect
}
function unsubscribe(listenerFunc) {
listeners = listeners.filter((l) => l !== listenerFunc)
}
return {
get,
set,
subscribe,
}
}
const simpleStore = makeObservable({ count: 0 })
const useStore = () => {
const [counter, setCounter] = useState(simpleStore.get())
useEffect(() => {
return simpleStore.subscribe(setCounter)
}, [])
const actions = useMemo(() => {
return {
incrementCount: () => simpleStore.set({ ...counter, count: counter.count + 1 }),
decrementCount: () => simpleStore.set({ ...counter, count: counter.count - 1 }),
}
}, [counter])
return {
state: counter,
actions
}
}
const App = () => {
const { state, actions } = useStore()
return (
<div>
{state.count}
<button
onClick={() => actions.incrementCount()}
>
INCREMENT
</button>
<button
onClick={() => actions.decrementCount()}
>
DECREMENT
</button>
</div>
)
}
const Tabs = () => {
const { state, actions } = useStore()
return (
<div>
{state.count}
<button
onClick={() => actions.incrementCount()}
>
INCREMENT
</button>
<button
onClick={() => actions.decrementCount()}
>
DECREMENT
</button>
</div>
)
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
ReactDOM.render(
<Tabs />,
document.getElementById('tabs')
);
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<div id="app"></div>
<div id="tabs"></div>

感谢streletss在makeObservable&自定义挂钩

最新更新