Skip to content

Managing child components

Nathan Ridley edited this page Aug 6, 2016 · 1 revision

Let's start by creating a very simple application and use a collection just to manage some predefined child components. The component examples below are overly simplistic of course, as we're just demonstrating a concept. In reality, sections of functionality would be broken out into separate components only when there is value to managing them independently.

import most from 'most';
import {run} from '@cycle/most-run';
import {div, h1, header, main, nav, p, makeDOMDriver} from '@motorcycle/dom';
import Collection from '@motorcycle/collection';

function Header(sources) {
  const view$ = most.just(
    header('.tutorial-header', [
      h1('Component Collections Tutorial')
    ])
  );
  return {
    DOM: view$
  };
}

function Navigation(sources) {
  const view$ = most.just(
    nav('.tutorial-nav', [
      div('Nav goes here.')
    ])
  );
  return {
    DOM: view$
  };
}

function Content(sources) {
  const view$ = most.just(
    main('.tutorial-content', [
      p('Welcome to the tutorial!')
    ])
  );
  return {
    DOM: view$
  };
}

function App(sources) {
  const header = Header(sources);
  const navigation = Navigation(sources);
  const content = Content(sources);

  // Here we'll use a collection in the simplest way possible; by using it to
  // streamline the management of our child components. Note that even though
  // we're setting items by key, the collection retains items the order in which
  // they were added, so you can be sure they'll always be returned in the order
  // you expect.

  const components = Collection()
    .setInstance('header', header)
    .setInstance('nav', navigation)
    .setInstance('content', content);

  // Now that the collection is managing our child components, we can combine
  // the views easily and use them as part of our app view. The `combineObject`
  // static method combines the latest values from the specified sink in each
  // child component and emits an updated object containing key/value pairs of
  // for latest value emitted by each component.

  const view$ = components.combineObject('DOM')
    .map(({header, nav, content}) => div('.container', [header, nav, content]));

  return {
    DOM: view$
  }
}

run(App, {
  DOM: makeDOMDriver('#app')
});

Alternatively, rather than using combineObject, we could use combineArray if we would prefer the child components to be emitted as an array rather than an object of key/value pairs, like so:

const view$ = components.combineArray('DOM')
  .map(([header, nav, content]) => div('.container', [header, nav, content]));

Tutorial and Guide

  • [Managing child components](Managing child components)
  • [Replacing a child component when state changes](Replacing a child component when state changes)
  • [Combining multiple sinks from child components](Combining multiple sinks from child components)
  • [Simple merging of a common sink to a derivative stream](Simple merging of a common sink to a derivative stream)
  • [Dynamic lists of child components](Dynamic lists of child components)
  • [Managing lists of components that don't have a key](Managing lists of components that don't have a key)
  • [Handling multiple component types in a single list](Handling multiple component types in a single list)
  • [Taking control of a component's lifecycle within a list](Taking control of a component's lifecycle within a list)

API Reference

  • [Quick Reference](API Quick Reference)
  • [Detailed Reference](API Detailed Reference)

Clone this wiki locally