Skip to content

Instantly share code, notes, and snippets.

@fatso83
Last active June 3, 2023 08:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fatso83/4e5823b111490582c9b72ae79f923e75 to your computer and use it in GitHub Desktop.
Save fatso83/4e5823b111490582c9b72ae79f923e75 to your computer and use it in GitHub Desktop.
Code Sandbox weirdness

CODESANDBOX ODDITIES

Code Sandbox oddities observed while working on LogicRoom exercises

codesandbox.io does its best to give the impression of a locally running environment, but the abstraction is sometimes a bit leaky. Here's some weirdness (with possible fixes)

Delayed execution of console.log

The console.log statement is actually proxied via a server and executed at a later stage. That sometimes results in weird behaviours, as the value of some field on an object can be different when it is printed than when it was logged ... The fix is making something like this and using that instead:

// logger.js
let loggerCount = 1;
export default function createLogger(name) {
  const loggerId = loggerCount++;
  return (...args) =>
    console.log(`[${loggerId}] ${name}:`, ...JSON.parse(JSON.stringify(args)));
}

This will force immediate evaluation of your arguments. Use it like this:

const log = createLogger('Presenter');
...
log(something, myObj)

The React Fast-Refresh does not unmount the old React tree

The fast-refresh functionality works differently than when working offline with something like webpack or Vite and makes cleaning up subscriptions/observers impossible, as there are no life-cycle hooks to hook into. Usually, on some change to the root components, they would be unmounted and the useEffect cleanup function would be called on changes.

While not exactly a huge problem, it causes some weird effects one might want to know about when working on exercises that involve react components observing Observable data models, as the listeners will keep reacting to changes long after the components have had new listeners set up. See this sandbox for an example. Changing the comment in line 11 in Compononent.jsx (// increment: 1) a couple of times will seemingly reload the page each time, but you now see that the console now prints this on a change to the values:

index.js:27 [4] Presenter: Got new value {fName: 'Jon', lName: 'Smith'}
index.js:27 [7] Presenter: Got new value {fName: 'Jon', lName: 'Smith'}
index.js:27 [10] Presenter: Got new value {fName: 'Jon', lName: 'Smith'}
index.js:27 [13] Presenter: Got new value {fName: 'Jon', lName: 'Smith'}
index.js:27 [16] Presenter: Got new value {fName: 'Jon', lName: 'Smith'}
...
[5] Child: vm {formattedString: 'Hello your name is Jon Smith'}
index.js:27 [8] Child: vm {formattedString: 'Hello your name is Jon Smith'}
index.js:27 [11] Child: vm {formattedString: 'Hello your name is Jon Smith', childChildVm: 'Jon'}
index.js:27 [14] Child: vm {formattedString: 'Hello your name is Jon Smith', childChildVm: 'Jon'}
index.js:27 [17] Child: vm {formattedString: 'Hello your name is Jon Smith', childChildVm: 'Jon'}
...

This means that not only is the state not cleaned up, but worse: all the old React trees are kept on change! So you have multiple versions of your app running. This will of course cause some confusion as to why your breakpoints are being hit 15 times instead of just a single time as you expected :) A hard reload fixes it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment