1
votes

I'm refactoring some React code to have a more flexible approach.

  • I have an abstract component that extends React.Component, let's say class ATable extends React.Component.
  • Another table extends this table like so: class FooTable extends ATable
  • Some other table does the same: class BarTable extends ATable
  • The (abstract) ATable component has a constructor method that provides bindings to other components:

ATable:

constructor(...args) {
    super(...args);
    this.components = {
        tableHead: TableHead,  // other (semi) abstract classes
        tableBody: TableBody,
        tableRow: TableRow,
        (...)
    }
}

render() {
    <section>
        <this.components.tableHead (...) />
        (...)
    </section>
}
  • FooTable can override some of this.components to make components pluggable. This happens like this:

FooTable:

constructor(...args) {
    super(...args);
        this.components.tableHead: FooHead
    }
}

class FooHead extends TableHead {}  // FooHead <- TableHead <- React.Component

The goal is to make the table (which in reality is more complex) a pluggable system.

The issue here is that if the props of FooTable changes, render() events all the way down to TableHead are being called but no DOM updates are visible. Before the abstraction everything seemed to work OK.

How is this possible and how can I solve this?

1
Have you considered using higher order components instead of using extends ? Or, for that matter, just normal component composition? - azium
Hmm, don't you need to return section inside render() {} if it's not declared with an arrow function? - user1641172
Try these two links Extending React components and Subclassing components. They're good examples of composition best practices. - Colin Whitmarsh
There already is a lot of composition, in this case it's useful to have some more flexibility. Mixins would be a good solution but unfortunately this is not supported in es6 according to the documentation. - Sven van de Scheur

1 Answers

0
votes

Turns out the problem was not the extension of classes but me trying to refactor...

Accidentally parts that were rendered were set to the state in the constructors chain. This of course, doesn't get updated.

The result was that the Component registered a props change, called the entire lifecycle (I could log the new props on render) but still no change because the props where never applied to the state.

With that fixed everything works OK now.