Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

316
Vistas
Why Mobx observer is not triggering re-render on React recurrent component?

I am trying to create a recursive component that stores it's state in a mobx observable object.

For some peculiar reason, if the observable links another observable in it's properties, the observer hoc from mobx-react-lite does not trigger re-render, when the observable state changes.

Here is the example, where the elements, that are more than 1 deep, are not re-rendered, when the observable state changes.

...
const NodeView = (props: { node: Node }) => {
  useEffect(() => {
    autorun(() => {
      console.log(`(autorun) ${props.node.label} is expanded: ${props.node.expanded}`);
      // WRONG: when the node is a child of another node, this runs, but the NodeView is not re-rendered
    });
  }, []);

  console.log(`rerendering ${props.node.label} `);

  return (
    <>
      <div
        className="nodeHeader"
        onClick={action(() => {
          props.node.expanded = !props.node.expanded;
        })}
      >
        {props.node.label}
      </div>
      {props.node.expanded && (
        <div className="row">
          <div className="offset" />
          <div className="column">
            {props.node.children.map((child, index) => (
              <NodeView key={index} node={child} />
            ))}
          </div>
        </div>
      )}
    </>
  );
};
export default memo(observer(NodeView));

Here is how observable objects are created:

...
interface Node {
  label: string;
  expanded: boolean;
  children: Node[];
  nonObservedStuff: any;
}

const turnIntoObservable = (node: Node) => {
  const children = node.children.map((child) => turnIntoObservable(child));

  let observableNode: Node = { ...node, children };

  // i'm trying to make observable not all, but only some specific properties
  observableNode = makeObservable(observableNode, {
    expanded: true,
    children: observable.shallow
  });

  return observableNode;
};

let rootNodes: Node[] = ...

rootNodes = rootNodes.map((node) => turnIntoObservable(node));

Here is codesandbox demo

Why changing state of an observable, that is linked by another observable in it's properties, does not cause to re-render of a component, that observes that observable?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

You are exporting observer component (export default memo(observer(NodeView));), but inside NodeView itself you are using non-observer NodeView

You need to wrap it with observer right away, so recursive version would be reactive too:

const NodeView = observer((props: { node: Node }) => {}

Also, memo is applied automatically for all observer components, you don't need to manually reapply it.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda