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.
CodePudding user response:
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 logo from './logo.svg'
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