🛠️ Tiny: Passing props to descendants

Hey ,

I'm thrilled to help you learn JavaScript. Unfortunately, you've landed on a page where you cannot access with your current purchase.

Please upgrade (use this link) access this content.

I'm super eager to help you learn more!

🛠️ Tiny: Passing props to descendants

When you create complex apps, there’s a high chance you need to create components that are nested in deeper components. This means there are several layers of components.

One simple way of illustrating this structure is to have layers of children components that need to access the main component’s count value.

When we click the button, we want to increase the count value in all descendant elements.

Tiny doesn’t support this now, so let’s find a way to make it work. The starter files for this lesson can be found in the link above.

The Structure

The structure for this demo is simple: We have a main component that passes props into the child.

Tiny({
  // ...
  template () {
    return `
      <div class="component parent-component flow">
        <h1>Parent Counter</h1>
        <p>Count: ${this.state.count}</p>
        <button tiny-listener="[click, increaseCount]">Increase count by 1</button>

        <div tiny-component="Child" tiny-props="[count, state.count]"></div>
      </div>`
  }
})

We also have a Child Component that passes props into the a Descendant component. In this case, we need to pass props.count down since count is present in props.

export default Tiny({
  components: {
    Descendant
  },

  template () {
    return `
      <div class='component child-component flow'>
        <h2>Child Component</h2>
        <p>Parent Count: ${this.props.count}</p>

        <div tiny-component="Descendant" tiny-props="[count, props.count]"></div>
      </div>
    `
  }
})

The Descendant is a simple component that logs the ancestor count.

export default Tiny({
  template () {
    return `
      <div class='component total-component flow'>
        <h2>Descendant Component</h2>
        <p>Ancestor Count: ${this.props.count}</p>
      </div>
    `
  }
})

Everything here is what I’ve written into the Starter file. They are logical and correct. But, if you open up page, you’ll notice the descendant component is missing.

There’s a simple fix.

Fixing the missing descendant

When we render children components previously, we did not account for further descendants being present inside each child component.

To fix this, we need to run _renderChildComponents again inside _renderChildComponents. This creates a recursive function that runs over and over again, until there are no more descendants.

export default function Tiny (options) {
  // ...
  function _renderChildComponents () {
    const compEls = element.querySelectorAll('[tiny-component]')
    for (const compEl of compEls) {
      // ...
      _renderChildComponents(childComp)
    }
  }
  // ...
}