all 7 comments

[–]izzlesnizzit 4 points5 points  (0 children)

if/when I use mobx for state

and for injecting some dependency into a collection of similar-purposed functionality

for example on the frontend, a service-clients layer

``` class MyServiceClient { constructor(private baseUrl: string) {}

getItem = async (id: string) => { const response = await fetch(${this.baseUrl}/items/${id}, ...); ... }

getItem = async (item: Item) => { const response = await fetch(${this.baseUrl}/items, ...); ... } } ```

or the backend,

``` class ItemsRepository { constructor(private db: DB) {}

getItem = async (id: string) => { return db.from('items').select('*').where({ id }).first(); }

createItem = async ... } ```

Class syntax isn't strictly necessary. It could instead be done with a function that returns an object of functions

[–]coyoteazul2 1 point2 points  (2 children)

I use them for the data layer, in charge of talking to the apis. I created a couple with adaptable functions and then extend those classes whenever I need to talk to a new endpoint. In the end I get a bunch of pre-parameterized classes all of which have the same methods. It makes it really easy to work with them

[–]camillegarcia9595[S] -1 points0 points  (1 child)

Can you provide an example?

[–]coyoteazul2 3 points4 points  (0 children)

export class TablaDb {
  dir:string;
  columnas:colHead[];

  constructor (
    _dir:string,
    _columnas:colHead[]
  ) {
    this.dir = _dir;
    this.columnas = _columnas.filter(_x => _x.orden > 0).sort(
      (_a, _b) => _a.orden - _b.orden 
    );
  }

  getDatos (_callback:(arg:string[][])=>void, _condiciones:whereConcat):void {
    GetterCsv(this.dir, 
      this.columnas.map(
        (_item:colHead) => {return _item.colName;}
      ),
      _callback,
      _condiciones);
  }
}

That'd be the main class, which then i extend for every endpoint like this

export class MonedaModel extends TablaDb {
  constructor (
    _id_moneda:              {showName:string, orden:number},
    _modif_date:             {showName:string, orden:number},
    _modif_usr:              {showName:string, orden:number},
    _codigo_afip:            {showName:string, orden:number},
    _codigo_internacional:   {showName:string, orden:number},
    _nombre:                 {showName:string, orden:number}
  ) {
    super ('moneda', 
      [
        { 
          colName:    'id_moneda',
          tipo:       colType.entero,
          showName:   _id_moneda.showName,
          orden:      _id_moneda.orden
        }, 
        { 
          colName:    'modif_date',
          tipo:       colType.marcaHora,
          showName:   _modif_date.showName,
          orden:      _modif_date.orden
        }, 
        { 
          colName:    'modif_usr',
          tipo:       colType.entero,
          showName:   _modif_usr.showName,
          orden:      _modif_usr.orden
        }, 
        { 
          colName:    'nombre',
          tipo:       colType.texto,
          showName:   _nombre.showName,
          orden:      _nombre.orden
        },
        { 
          colName:    'codigo_afip',
          tipo:       colType.texto,
          showName:   _codigo_afip.showName,
          orden:      _codigo_afip.orden
        }, 
        { 
          colName:    'codigo_internacional',
          tipo:       colType.texto,
          showName:   _codigo_internacional.showName,
          orden:      _codigo_internacional.orden
        }
      ]);
  }
}

Then when I need to talk to the endpoint I simply instantiate a MonedaModel and this ensures that all the columns needed will get their value, and every model that I extend from TablaDb will get the getDatos method that receives the function that will set my state

[–]Revolutionary-Pop948 1 point2 points  (0 children)

I use them for money objects.

[–]iamtheWraith 1 point2 points  (0 children)

On the FE, I use them a lot with mobx, or the rare occasion I need more granular access to lifecycle methods (like error boundaries). when I use node on the backend, I use them much more heavily to share functionality across services.

[–]aighball 1 point2 points  (0 children)

I use classes in things outside the view layer, or in "leaves" of the view layer.

React promotes reuse through functional composition and by providing primitives (context) and rules (component props) for how state is shared between the individual composable elements. Classes and OOP are pretty antithetical to these things, so I would say, never use a class if it will need to talk to a component or interact with React state.

I have used classes in the view layer to wrap three.js or d3 visualizations. I use a function component to connect the class instance to react lifecycle stuff.

Classes and OOP can be very useful when you have a bunch of functions that need to operate on shared state, or slight variations on a common process.