cerebral/overmind

[BUG] proxy-state-tree - You are mutating the path

tianlizhao opened this issue · 1 comments

// state.ts
import { statemachine } from "overmind";

type States =
  | {
      current: "A";
    }
  | {
      current: "B";
    }
  | {
      current: "C";
    };
type Events = {
  type: "ON";
};

export const myMachine = statemachine<States, Events>({
  A: {
    ON: () => ({ current: "B" })
  },
  B: {
    ON: () => ({ current: "C" })
  },
  C: {
    ON: () => ({ current: "A" })
  }
});

class Model {
  count = 0;
  myMachine = myMachine.create({ current: "C" });
  send() {
    this.myMachine.send("ON");
  }
  countDown() {
    setInterval(() => {
      this.count++;
    }, 1000);
  }
}

export const state = {
  model: new Model()
};

// actions.ts
import { Context } from ".";

export const onInitializeOvermind = async ({
  state,
  actions,
  effects
}: Context) => {
  // actions.sendAndTiming(); // Don't work
  actions.send();
  actions.countDown();
};

export const sendAndTiming = ({ state, actions }: Context) => {
  state.model.send();
  state.model.countDown();
};

export const send = ({ state, actions }: Context) => {
  state.model.send();
};
export const countDown = ({ state, actions }: Context) => {
  state.model.countDown();
};
import "./styles.css";
import { useActions, useAppState } from "./overmind";
import { useEffect } from "react";

export default function App() {
  const state = useAppState();
  const actions = useActions();
  useEffect(() => {
    // Don't work
    actions.countDown();
  }, []);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <div>{state.model.count}</div>
    </div>
  );
}
/**
Error
proxy-state-tree - You are mutating the path "model.count", but it is not allowed. The following could have happened:
        
        - The mutation is explicitly being blocket
        - You are passing state to a 3rd party tool trying to manipulate the state
        - You are running asynchronous code and forgot to "await" its execution
*/

Why can't we call it together?

Going through and cleaning up Issues. I am not sure this is a bug:

  • state contains one prop which is 'model'
  • model is initialised with as a new Class() - thus model is then an object
  • the object is proxified, as expected, since it is now on the tree
  • you then have a side effect using setInterval which tries to modify a sub-property of that model property in the proxy-state-tree

Thus this is behaving as designed as I see? The proxified tree should only be modified via an action.

As this is a side effect, if you can't change the class, consider using it as an effect in overmind, rather than directly part of state.

Closing this but reopen if you disagree