我写了一个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
&自定义挂钩