5

I cant figure out mobx-react...

How do I pass props from a mobx observable to a mobx-react observer?

The code below doesn't works, but I feel like it should. Can someone tell me what is going wrong?

let mobxData = observable({information: "this is information"});

@observer class Information extends React.Component {
    render() {
        console.log(this.props.mobxData.information);
        return (
            <h1>class: {this.props.mobxData.information}</h1>
        )
    }
};

const StatelessInformation = observer(({mobxData}) => {
    console.log(mobxData.information);
    return <h1>stateless: {mobxData.information}</h1>
});

ReactDOM.render(
    <div>
        <Information/>
        <StatelessInformation/>
    </div>,
    document.getElementById('app')
);
David Schumann
  • 13,380
  • 9
  • 75
  • 96
joeydebreuk
  • 376
  • 2
  • 8
  • 1
    I'm not quite sure what you are asking. [**It works for me**](http://jsbin.com/jeyagesira/edit?js,output). – Tholle Aug 17 '17 at 13:55
  • Thanks for creating the JSBin. I understand if you pass them trough a parent it works, but shouldnt mobx take care of this? – joeydebreuk Aug 17 '17 at 14:06
  • I guess this is where I go wrong though. – joeydebreuk Aug 17 '17 at 14:07
  • If you want `mobxData` to be available without explicitly passing them through a parent, you might want to look into [**Provider and inject**](https://github.com/mobxjs/mobx-react#provider-and-inject). You could also remove `this.props.mobxData.information` and write `mobxData.information` in the class, and remove the descructuring in the stateless version, if you want to access `mobxData` directly. – Tholle Aug 17 '17 at 14:10
  • 1
    And if I have a more complex application with a store holding around 10 variables, would it hurt to inject that into every component? Should I write different inject models that get data from the store? What is the best way to go about that? Thanks again !!! – joeydebreuk Aug 17 '17 at 14:15
  • 2
    No problem! If you have a `CarStore` with 10 variables, it's no problem injecting that into every component that needs any one those 10 variables. If you have a `CarStore` and a `GarageStore`, and you only need variables from the `CarStore` in a particular component, there is no need to inject the `GarageStore` into that component, of course. – Tholle Aug 17 '17 at 14:26
  • 1
    What if a component doesnt need all 10 vars? If I only need 1 var out of CareStore, I dont have to write a seperate provider, and just inject 10 vars? Or will that mess up the performance (you know... all the rerendering...). Big shout-out to you and the entire stackoverflow community, should have asked here earlier. Saves so much time. – joeydebreuk Aug 17 '17 at 14:34
  • 1
    [**MobX only re-renders when the observables the observer depends on changes**](http://jsbin.com/morunogija/edit?js,console,output), so that's no problem at all. – Tholle Aug 17 '17 at 14:41
  • 1
    also, don't forget extra lifecycle stuff like, `componentWillReact` etc – Dimitar Christoff Aug 17 '17 at 15:23

1 Answers1

2

I've not done much mobx lately and not tested this but typically you'd have a provider somewhere and then use the @inject to pass stores as props

Consumer of information:

import { observer, inject } from 'mobx-react'

@inject('information')
@observer
class Information extends React.Component {
  render(){
    {this.props.information.foo}
  }
}

model level - very basic

import { observable, action } from 'mobx'

class Information {
  @observable foo = 'bar'
  @action reset(){
    this.foo = 'foo'
  }
}

export new Information()

Root provider level

import { Provider } from 'mobx-react'
import Information from ./information'

<Provider information={Information}>
  <Information />
</Provider>

// test it... 
setTimeout(() => {
  Information.foo = 'back to foo'
}, 2000)

but ultimately you can probably work with whatever you pass in the Provider

Under the hood, the provider is probably just passing context via childContextType and contextType when a HOC memoises it and maps to props.

Dimitar Christoff
  • 26,147
  • 8
  • 50
  • 69