mardi 4 juillet 2017

What's the proper React state management for holding rows of unmounted JSX?

We have a crazy DOM hierarchy, and we've been passing JSX in props rather than embedding children. We want the base class to manage which documents of children are shown, and which children are docked or affixed to the top of their associated document's window.

  • List (crazy physics writes inline styles to base class wrappers)
    1. Custom form (passes rows of JSX to Base class)
      • Base class (connects to list)
    2. Custom form (passes rows of JSX to base class)
      • Base class (connects to list)

Is there some trick to dealing with collections of JSX? Am I doing something wrong? This all seems overly-complicated, and I would rather not worsen the problem by following some anti-pattern.


The problem is that we're passing deeply nested JSX, and state management / accessing refs in the form is a nightmare.


I don't want to re-declare every row each time, because those rows have additional state attached to them in the Base Class, and the Base Class needs to know which rows actually changed. This is pretty easy if I don't redeclare the rows.

I don't know how to actually deal with rows of JSX in Custom Form.

  1. Refs can only be appended in a subroutine of render(). What if CustomForm wants to measure a JSX element or write inline CSS? How could that JSX element exist in CustomForm.state, but also have a ref? I could cloneElement and keep a virtual DOM (with refs) inside of CustomForm, or depend on the base class to feed the deeply-nested, mounted ref back.
  2. I believe it's bad practice to write component state from existing state. If CustomForm state changes, and I want to change which rows are passed to BaseClass, I have to throttle with shouldComponentUpdate, re-declare that stage document (maintaining row object references), then call setState on the overarching collection. this.state.stages.content[3].jsx is the only thing that changed, but I have to iterate through every row in every document in BaseClass when it sees that props.stages changed, in order to find that props.stages.content[3].jsx changed.

custom-form.js

render () {
  return <BaseClass stages={this.stages()}/>
}

stages () {
  if (!this._stages) this._stages = { title: this.title(), content: this.content() };
  return this._stages;
}

title () {
  return [{
    canBeDocked: false,
    jsx: (
      <div>A title document row</div>
    )
  }
}

content () {
  return [{
    canBeDocked: false,
    jsx: (
      <div>Hello World</div>
    )
  }, {
    canBeDocked: true,
    jsx: (
      <div>Yay</div>
    )
  }
}

Aucun commentaire:

Enregistrer un commentaire