I'm trying to pass global state created like this in micro front end applications. But the problem is that I have to "watch" for changes somehow in order to setState for example in a React app.
globalState.js
import { reactive } from 'vue'
const globalState = reactive({
counter: 0
})
export default globalState
In Vue micro front ends im doing this and it is working fine
import { createApp } from 'vue'
import App from './App.vue'
export default (rootEl, globalState) => {
const app = createApp(App)
app.config.globalProperties.globalState = globalState
app.mount(rootEl)
}
However in a React app I pass the reference correctly but when counter value changes I have to somehow detect it and call setState in order to rerender the change. The Question is how can I watch for changes of this reactive object reference outside Vue ecosystem.
The Reactivity API is available as standalone libraries (separate from the vue
package) that can be used outside the context of Vue.
@vue/reactivity
includes reactive()
/ref()
. And @vue-reactivity/watch
includes watch()
/watchEffect()
.
For example, you could use a watchEffect
(or watch
) to log the new value of globalState.counter
and display it in an element on the page:
// main.js
import { watchEffect } from '@vue-reactivity/watch'
import globalState from './globalState'
watchEffect(() => {
console.log('counter', globalState.counter)
document.querySelector('#count').innerHTML = globalState.counter
})
// globalState.js
import { reactive } from '@vue/reactivity'
const globalState = reactive({
counter: 0
})
export default globalState
In a React app, you could use a watch
to log the new value of globalState.counter
and then call a component's setState()
to re-render the component:
import { useState, useEffect } from 'react'
import { watch } from '@vue-reactivity/watch'
import globalState from './globalState'
import GlobalCounterButton from './GlobalCounterButton'
function App() {
const [count, setCount] = useState(0)
useEffect(() => {
const unwatch = watch(
() => globalState.counter,
(newValue, oldValue) => {
if (newValue !== oldValue) {
console.log('counter', newValue)
setCount(newValue)
}
}
)
return () => unwatch()
})
return (
<div>
<GlobalCounterButton />
<h2>count is: {count}</h2>
</div>
)
}
export default App