Closed 1eeing closed 8 months ago
I have a problem, when state chanegd if a parent vue component use Observer to wrap it, the child component will rerender. How to memo the child vue component so that it can render once.
@1eeing we need a reproduce online demo to check your issue (codesandbox or whatever) , thanks.
@1eeing we need a reproduce online demo to check your issue (codesandbox or whatever) , thanks.
@iChenLei current Observer implementation will re-render every child componenets, without tree-seeking or something like this.
https://vuejs.org/api/built-in-special-attributes.html#key
mounted() {
this.dispose = reaction(() => this.$slots.default?.(), () => {
this.forceUpdate()
}, {
requiresObservable: true,
})
},
unmounted() {
this.dispose()
},
methods: {
forceUpdate() {
this.key++
},
},
render() {
return h(this.$slots.default!, { key: this.key }) // here
},
@wobsoriano Any idea ?
I have no idea yet of a way to only apply changes to elements that have been updated and are using an observable.
For now, it's best to use useLocalObservable
composable, or only wrap the components with Observer
that needs to be observed:
<script setup lang="ts">
import { observable, runInAction } from 'mobx'
import { Observer } from 'mobx-vue-lite'
import AnotherComponent from './components/AnotherComponent.vue'
const data = observable({ name: 'John' })
const changeName = () => {
runInAction(() => {
data.name = 'Jane ' + Date.now()
})
}
</script>
<template>
<Observer>
<div>Name: {{ data.name }}</div>
<button @click="changeName">Change name</button>
<div>Name: {{ data.name }}</div>
</Observer>
<AnotherComponent />
</template>
They are very simple components, if we binding an array to complex component, it will be reset and lost all state (input, checkbox, ...) each time array changed.
<Observer>
<div>Name: {{ data.name }}</div>
<button @click="changeName">Change name</button>
<div>Name: {{ data.name }}</div>
</Observer>
@huybuidac I agree. Do you have a solution in mind?
render() { return h(this.$slots.default!, { key: this.key }) }
forceUpdate` causes key change, which will cause all components wrapped in Observer Component to be re mounted and have their lifecycle restarted. Normally, the parent component will update the child components and they will also be re mounted instead of re-mounted. Can we consider replacing the prop injection of the key.
h(this.$slots.default!, { extraMobxVueKey: this.key })
like this.
@wobsoriano
@bdwenxi I just released a new version with that request. It passed the tests, which is interesting. Would you mind explaining it to me? Why does using a different key fix it? Thank you!
Looks like this fixes the issue. Can anyone confirm?
Feel free to reopen!
如题,求教这个问题如何解决