Skip to content

Latest commit

 

History

History
200 lines (163 loc) · 4.85 KB

Migrating.md

File metadata and controls

200 lines (163 loc) · 4.85 KB

WebCell v2 to v3 migration

React-style State has been totally dropped

WebCell v3 is heavily inspired by the Local Observable State idea of MobX, and not only React, Web Components can be much easier to manage the Inner State & Logic, without any complex things:

  1. State type declaration
  2. this.state declaration & its type annotation/assertion
  3. this.setState() method calling & its callback
  4. confusive Hooks API...

Just declare a State Store class as what the Global State Managment does, and initial it on the this (a Web Component instance). Then use the state, and observe them, as MobX's usual, everything is done.

import {
    component,
+   observer,
-   mixin,
-   createCell,
-   Fragment
} from 'web-cell';
+import { observable } from 'mobx';

-interface State {
+class State {
+   @observable
-   key: string;
+   accessor key = '';
}

@component({
    tagName: 'my-tag'
})
+@observer
-export class MyTag extends mixin<{}, State>() {
+export class MyTag extends HTMLElement {
-   state: Readonly<State> = {
-       key: 'value'
-   };
+   state = new State();

-   render({}: any, { key }: State) {
+   render() {
+       const { key } = this.state;

        return <>{value}</>;
    }
}

At the same time, shouldUpdate() {} life-cycle has been dropped. You just need to control the logic before states changed in your State class methods.

DOM properties become observable data

DOM properties aren't like React's props, they're reactive. They are not only responsible to update Component views, but also synchronize with HTML attriutes.

MobX's @observable & reaction() are awesome APIs to implement these above with clear codes, so we add mobx package as a dependency:

npm install mobx

On the other hand, mobx-web-cell adapter has been merged into the core package.

+import { JsxProps } from 'dom-renderer';
import {
-   WebCellProps,
    component,
    attribute,
-   watch,
+   observer,
-   mixin,
-   createCell,
-   Fragment
} from 'web-cell';
-import { observer } from 'mobx-web-cell';
+import { observable } from 'mobx';

-export interface MyTagProps extends WebCellProps {
+export interface MyTagProps extends JsxProps<HTMLElement> {
    count?: number
}

@component({
    tagName: 'my-tag'
})
@observer
-export class MyTag extends mixin<MyTagProps>() {
+export class MyTag extends HTMLElement {
+   declare props: MyTagProps;

    @attribute
-   @watch
+   @observable
-   count = 0;
+   accessor count = 0;

-   render({ count }: MyTagProps) {
+   render() {
+       const { count } = this;

        return <>{count}</>;
    }
}

control Render Target with Shadow DOM mode option

render to children

import {
    component,
-   mixin
} from 'web-cell';

@component({
    tagName: 'my-tag',
-   renderTarget: 'children'
})
-export class MyTag extends mixin() {
+export class MyTag extends HTMLElement {
}

render to shadowRoot

import {
    component,
-   mixin
} from 'web-cell';

@component({
    tagName: 'my-tag',
-   renderTarget: 'shadowRoot'
+   mode: 'open'
})
-export class MyTag extends mixin() {
+export class MyTag extends HTMLElement {
}

move Shadow CSS injection into render()

This makes Shadow CSS to react with Observable Data updating.

+import { stringifyCSS } from 'web-utility';
import {
    component,
-   mixin
} from 'web-cell';

@component({
    tagName: 'my-tag',
-   renderTarget: 'shadowRoot',
+   mode: 'open',
-   style: {
-       ':host(.active)': {
-           color: 'red'
-       }
-   }
})
-export class MyTag extends mixin() {
+export class MyTag extends HTMLElement {
    render() {
        return <>
+           <style>
+               {stringifyCSS({
+                   ':host(.active)': {
+                       color: 'red'
+                   }
+               })}
+           </style>
            test
        </>;
    }
}

replace some APIs

  1. mixin() => HTMLElement & its Sub-classes
  2. mixinForm() => HTMLElement & @formField
  3. @watch => @observable accessor

Appendix: v3 prototype

  1. Legacy architecture
  2. Modern architecture
  3. MobX lite