Star

Created With

Components


Components are functions for rendering parts of the UI:

greetings.tsx
1linkexport function Greetings({to}, renderer) {

2link return <h1>Hellow {to}!</h1>;

3link}

index.tsx
1linkimport { Greetings } from './greetings';

2link

3linkrenderer.render(

4link <Greetings to='World'/>

5link).on(document.body);


Playground
1linkconst records = state([]);

2linkconst add = () => records.set(records.get().concat(new Date()));

3linkconst clear = () => records.set([]);

4link

5linkfunction Record({ record }, renderer) {

6link const remove = () => records.set(records.get().filter(r => r !== record.get()));

7link

8link return <div>{ record } <button onclick={remove}>X</button></div>

9link}

10link

11linkrenderer.render(

12link <>

13link <button onclick={add}>Add</button>

14link <button onclick={clear}>Clear</button>

15link <List of={records} each={record => <Record record={record}/>}/>

16link </>

17link).on(document.body);

Playground

verified_user TYPE SAFETY

If you are using TypeScript, it is recommended to properly type-annotate your components for easier and safer re-use:

1linkimport { Source } from 'callbag-common';

2linkimport { RendererLike } from 'render-jsx';

3link

4linkexport interface GreetingsProps {

5link to: string | Source<string>

6link}

7link

8linkexport function Greetings(props: GreetingsProps, renderer: RendererLike<Node>) {

9link return <h1>Hello {props.to}!</h1>;

10link}




linkNaming Rules

Component function names MUST start with uppercase letters:

1link// 🚫 WRONG:

2linkfunction myComponent(...) { ... }

3link

4link// ✅ CORRECT:

5linkfunction MyComponent(...) { ... }


The second argument of a component function MUST be named renderer:

1link// 🚫 WRONG:

2linkfunction MyComp() { return <h1>~~~~Hellow!~~~~~~~</h1>~~~~~ } // --> renderer is not defined

3link

4link// ✅ CORRECT:

5linkfunction MyComp(_, renderer) { return <h1>Hellow!</h1> }

Learn Why



linkChildren

Child elements are passed to component functions as the third argument:

card.tsx
1linkexport function Card(_, renderer, children) {

2link return <div style={{

3link display: 'inline-block',

4link 'border-radius.px': 7,

5link 'padding.px': 16,

6link 'box-shadow': '0 3px 6px rgba(0, 0, 0, .25)',

7link }}>

8link {children}

9link </div>;

10link}

index.tsx
1linkimport { Card } from './card';

2link

3linkrenderer.render(

4link <Card>

5link Hellow There!

6link </Card>

7link).on(document.body);


Playground

👉 children is an array of child elements passed to the component:

unordered-list.tsx
1linkexport function UnorderedList(_, renderer, children) {

2link return <ul>

3link {children.map(child => <li>{child}</li>)}

4link </ul>;

5link}

index.tsx
1linkimport { UnorderedList } from './unordered-list';

2link

3linkrenderer.render(

4link <UnorderedList>

5link Hellow There!

6link <span>How are you doing?</span>

7link <div>Huh this is relatively neat</div>

8link </UnorderedList>

9link).on(document.body);


Playground

👉 For named child slots, it is recommended to use properties:

unordered-list.tsx
1linkexport function UnorderedList({footer}, renderer, children) {

2link return <>

3link <ul>

4link {children.map(child => <li>{child}</li>)}

5link </ul>

6link { footer || '' }

7link </>;

8link}

index.tsx
1linkimport { UnorderedList } from './unordered-list';

2link

3linkrenderer.render(

4link <UnorderedList footer={<>This is the end</>}>

5link Hellow There!

6link <span>How are you doing?</span>

7link <div>Huh this is relatively neat</div>

8link </UnorderedList>

9link).on(document.body);


Playground


linkLife-Cycle

Component functions are called only once, when they are used within JSX:

1linkconst Z = <MyComp x={42}/>

☝️ This is roughly equivalent to the following:

1linkconst Z = MyComp({ x: 42 }, renderer)


A component has two other important life-cycle events:

You can hook into these events using hooks:

1linkfunction MyComponent(...) {

2link this.onBind(() => ...)

3link this.onClear(() => ...)

4link}

Learn More

👉 More conveniently, you can track callbags (or subscriptions) between these two events (i.e. while created elements are on screen):

1linkexport function JinxCheck({ source }, renderer) {

2link this.track(pipe(

3link source,

4link subscribe(v => {

5link if (v === 13) {

6link alert('JINX!');

7link }

8link }),

9link ));

10link

11link return <small>Jinx-Check is Active!</small>

12link}

PlaygroundLearn More





Naming RulesChildrenLife-Cycle

Home Getting Started


Introductionchevron_right

Basicschevron_right

Reactivitychevron_right

Componentschevron_right

In-Depthchevron_right

Metachevron_right