three-csm icon indicating copy to clipboard operation
three-csm copied to clipboard

Side effects in constructor cause problems when used as a custom React Three Fiber component

Open itsdouges opened this issue 2 years ago • 0 comments

Heya! I've been setting up three-csm to work as a r3f component and I've mostly got it working but unfortunately there is one friction point - the side effects during class construction. This has been a friction point in other three classes, for example OrbitControls (see: https://github.com/mrdoob/three.js/issues/20575 if you're interested).

The solution would be to separate out the side effects from the constructor, adding them into a new function called attach or something similar. If the side effects are desirable for vanilla threejs scenes or ergonomics we could also keep the current behaviour and add the new behaviour under a constructor arg.

mrdoob looks to be keen on separating out side effects from constructors https://github.com/mrdoob/three.js/issues/20575#issuecomment-774527294

Happy to contribute, let me know what you think.


Edit: I have been able to work around this for now by creating a proxy class:

class CSMProxy {
  instance: CSM | undefined;
  args: Params;

  constructor(args: Params) {
    this.args = args;
  }

  set fade(fade: boolean) {
    if (this.instance) {
      this.instance.fade = fade;
    }
  }

  set camera(camera: Camera) {
    if (this.instance) {
      this.instance.camera = camera;
    }
  }

  set lightDirection(vector: Vector3 | Vector3Tuple) {
    if (this.instance) {
      this.instance.lightDirection = Array.isArray(vector)
        ? new Vector3().fromArray(vector).normalize()
        : vector;
    }
  }

  attach() {
    this.instance = new CSM(this.args);
  }

  dispose() {
    if (this.instance) {
      this.instance.dispose();
    }
  }
}

itsdouges avatar Nov 16 '22 00:11 itsdouges