Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component fails to re-render on props value change #40

Open
svicalifornia opened this issue Aug 19, 2021 · 2 comments
Open

Component fails to re-render on props value change #40

svicalifornia opened this issue Aug 19, 2021 · 2 comments

Comments

@svicalifornia
Copy link
Contributor

I started with your functional counter example here: https://codesandbox.io/s/mobx-counterfunctions-3sqv1

First I converted it to TypeScript and got that working. Next, I abstracted the counter div to a separate component:

// CountView.tsx

interface CountViewProps {
  count: number;
}

export default function CountView({count}: CountViewProps) {
  return <div className="counter">{count}</div>;
}

Then I refactored the App component to use CountView and to also log the count to console:

// index.tsx

import { observable } from "mobx";
import { cleanup, render } from "mobx-jsx";

import CountView from "./CountView";

function App() {
  const state = observable({ count: 0 })
  const timer = setInterval(() => {
    state.count++;
    console.log(state.count);
  }, 1000);
  cleanup(() => clearInterval(timer));
  return <CountView count={state.count} />;
}

render(App, document.getElementById("app"));

The console shows that the count is incrementing, but the count in the browser doesn't update — it's stuck at 0.

Why doesn't the CountView component re-render when state.count changes?

@svicalifornia
Copy link
Contributor Author

svicalifornia commented Aug 19, 2021

OK, I just found that the above issue was discussed already in issue #24. I think this deserves more explanation in the README, but for now, I'll cover my findings here.

Destructuring props outside of JSX snippets (either in the arguments list or in the render function body) doesn't work:

// This does NOT work; the component will not re-render when props.count changes.
export default function CountView(props: CountViewProps) {
  const {count} = props;
  return <div className="counter">{count}</div>;
}

Destructing props within a JSX snippet does work:

// This DOES work; changes to props.count will be rendered in the browser.
export default function CountView(props: CountViewProps) {
  return <div className="counter">{props.count}</div>;
}

I can understand why, since the CountView function is only run once in each lifecycle, and only the JSX snippets get observed and re-evaluated after that. But still, this was confusing as a newcomer!

Are there more docs for mobx-jsx beyond the README?

@ryansolid
Copy link
Owner

Not really. This was mostly a PoC when I was generalizing the approach I was developing with SolidJS. Most things that apply to Solid apply here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants