mobxjs / mobx-react

React bindings for MobX
https://mobx.js.org/react-integration.html
MIT License
4.85k stars 349 forks source link

child component doesnt update if store is passed via props #783

Closed schumannd closed 5 years ago

schumannd commented 5 years ago

I might be missing something fundamental here. I got the following setup

compA.js

@observer
class CompA {
  render() {
    <Text>{this.props.myStore.x}</Text>
  }
}

compB.js

import myStore from 'a/b/c/myStore.js';

class CompB {
  render() {
    <TouchableOpacity onPress={() => myStore.x = 'changed' />
  }
}

compC.js

import CompA from 'x/y/z/compA.js

@observer
@inject('myStore')
class CompC {
  render() {
    <CompA myStore={this.props.myStore}>
    <Text>{this.props.myStore.x}</Text>
    <CompB>
  }
}

myStore.js

class myStore {
  @observable x = 'not changed';
}

The state change triggered in CompB triggers a rerender in CompC. <Text>{this.props.myStore.x}</Text> then displays the updated value. However CompA does not rerender and the old value is still displayed there.

I have used a more complex version (invloving maps and iterating over them) elsewhere in the app, and there the state change is registered in CompA, and it does rerender. But in this case it doesn't.

In general, is this supposed to work? Or should/can stores not be forwarded by the injected component to its children? i.e. might the error lie in some detail I have not written down in this example?

danielkcz commented 5 years ago

Please provide a reproduction, eg. with CodeSandbox.

schumannd commented 5 years ago

do you have a template I can use? I didn't manage to get react-native running with mobx on codesandbox.

danielkcz commented 5 years ago

Well, you did not mention React Native at all :) But you can try with React. In case you cannot reproduce it with React then chances are it's RN issue most likely anyway because those code snippets look just fine.

jeremy-coleman commented 5 years ago

Inject then observe, @inject()@observe Comp

schumannd commented 5 years ago

@jeremy-coleman still broken afterwards.

In case anyone else wonders how I "solved" it: I just pass the observables as props to my components, not the whole store.

I guess using Components within components does not allow for store injection, or passing of whole stores as props.

Edit: still running into update issues. So it is probably something else.

danielkcz commented 5 years ago

We are still waiting for that reproduction if you want to see some fix. Don't worry about RN, try to reproduce with regular React.

schumannd commented 5 years ago

I spent a few hours on it and was not able to reproduce this problem in regular react. There it behaves as expected. Any pointers on how I can find where the rerender signal that should get through might get stuck?

danielkcz commented 5 years ago

The key point where re-render magic is happening is here...

https://github.com/mobxjs/mobx-react-lite/blob/a6bc7c225c7bb495840d9b972f84b9273e2b2879/src/useObserver.ts#L31

Sorry, without reproduction I am going to close this. Unless you are omitting some details (not on purpose), I don't see how it can be an issue of this lib.

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs or questions.