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)
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 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.