Reputation: 8674
When using MobX with React, I have 2 components. From the parent I send a prop to the child component like this:
import { computed } from 'mobx'
import { observer } from 'mobx-react'
@observer
class Parent extends React.Component {
@computed get user() {
const { gamer } = this.props;
}
render () {
return <div><Child user={this.user} /></div>
}
}
Child component:
import { observable } from 'mobx'
import { observer } from 'mobx-react'
@observer
class Child extends React.Component {
@observable owner = this.props.user;
render () {
return <div>{this.owner.name}</div>
}
}
The first time I run this with userX
passed, the child shows the correct userX
owner name, accessed via the @observable owner
. The issue is the second time I run this with a different user passed userY
, the child still shows userX
even though the prop passed to it is correctly userY
when I log it.
So the passed prop is different per user (as it should be), but the observable stays "locked" on the first user that was passed. Any idea why the observable isn't updating its value to the passed this.props.user
?
Update:
So I tried @computed
like this:
@computed get owner() {
return this.props.user;
}
but still the same issue. The only way I can seem to access the correct user, only in the render statement and directly from the passed prop as opposed to having mobx assign the prop value and read it from mobx observable/computed:
render() {
console.log(this.owner.name); // shows old data (even w/ observable or computed returning the passed prop)
console.log(this.props.user.name); // shows new data correctly without mobx
I just don't understand why the @observable
or @computed
don't return the correct new data. Is there anyway to have mobx correctly return the latest passed prop so the first console log works?
Upvotes: 2
Views: 2914
Reputation: 2807
I think that we you do @observable owner = this.props.user
, you do not create a reference to the original observable, but rather you create a new observable whose initial value will be the same as of the orginal one.
The solution (as it seems you already found) is to use the prop value directly in the Child component:
@observer
class Child extends React.Component {
render () {
return <div>{this.props.user.name}</div>
}
}
If you don't wanna do this, perhaps you can take a look at cloning* the observable using createViewModel from the mobx-utils package:
import { computed } from 'mobx'
import { observer } from 'mobx-react'
import { createViewModel } from 'mobx-utils'
@observer
class Child extends React.Component {
owner = createViewModel(this.props.user);
render () {
return <div>{this.owner.name}</div>
}
}
* Note: well, it is not exactly cloning, but the changes to user will get reflected in the owner object as well. Check the docs for more info.
Upvotes: 0