Component class

The Component class will be the bread and butter of our dynamic UI. Let's write an minimal implementation:

index.js

...

class Component {
  constructor(props) {
    this.props = props || {};
  }
  setState(partialNewState) {
    // Awesome things to come
  }
  //will be overridden
  render() {}
}

Exciting! We're going to implement the much used setState function ourselves! But, before we're going finish the Component class implementation we will we look at mounting first. We will definitly run into some problems, but these problems will let us define the requirements for the Component class better!

Mounting a Component with mountVComponent.

As you probably could have guessed we're going to define this function as mountVComponent. And it does a bit more work then the other mount functions. Let's see:

index.js
...

function mountVComponent(vComponent, parentDOMNode) {
  const { tag, props } = vComponent;

  // build a component instance. This uses the 
  // defined Component class. For brevity 
  // call it Component. Not needed ofcourse, new tag(props)
  // would do the same. 
  const Component = tag;
  const instance = new Component(props);

  // The instance or Component has a render() function 
  // that returns the user-defined vNode.
  const currentElement = instance.render();

  // the currentElement can be a vElement or a
  // vComponent. mountVComponent doenst't care. Let the mount()
  // handle that!
  const dom = mount(currentElement, parentDOMNode);

  //save the instance for later
  //references! 
  vComponent._instance = instance;
  vComponent.dom = dom;

  //append the DOM we've created.
  parentDOMNode.appendChild(dom);

  return dom;
}

React.js has a mountComponent function on it's ReactCompositeComponent or ReactDOMComponent.

The most important part is that we instantiate our Component with new Component(props). This creates a Component class, that has a render() function. The render function returns the vNodes and, we recurse again! It's all about recursion yo!

Now we need to update the mount function, so that it can handle vComponents.

index.js
...

function mount(input, parentDOMNode) {
  if (typeof input === 'string' || typeof input === 'number') {
    //we have a vText
    return mountVText(input, parentDOMNode);
  } 
  else if (typeof input.tag === 'function') {
    //we have a component
    return mountVComponent(input, parentDOMNode);
  }
  // for brevity make an else if statement. An
  // else would suffice :). 
  else if (typeof input.tag === 'string') {
    //we have a vElement
    return mountVElement(input, parentDOMNode)
  }
}

And we can define and render our new application as:

class App extends Component {
  render() {
    return createElement('div', { style: { height: '100px', background: 'red'} }, [
      createElement('h1', {}, [ this.props.message ])
    ]);
  }
}

const root = document.body;

mount(createElement(App, { message: 'Hello there!' }), root);

If the code is not working, or If I accidently skipped parts, please let me know. The code we should have at this point. can be found here

Awesome! We've now introduced Components!. We've built a Component Class which we can easily extend. We're making moves yoo! But, we're not utilizing the Components as we should, we introduced them for their powers..

Let's take a look at state.

results matching ""

    No results matching ""