Vanilla FP: The no-framework framework for building component-based UIs

boris_m1 pts0 comments

GitHub - abuseofnotation/vanilla-fp: The no-framework framework for building component-based purely-functional UIs. · GitHub

/" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

abuseofnotation

vanilla-fp

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star<br>124

main

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>8 Commits<br>8 Commits

README.md

README.md

app.js

app.js

index.html

index.html

user-edit.js

user-edit.js

vanilla-fp.js

vanilla-fp.js

volume-control.js

volume-control.js

View all files

Repository files navigation

The no-framework framework for building component-based purely-functional UIs.

About vanilla-fp

At the heart of vanilla-fp is not code but convention for how to build a component. A component is a pure-ish function that typically receives two parameters (called 'state' and 'setState', but can vary across components) which provide the component with a state and with a function for altering its state and returns a UI component, using the building blocks provided by the framework:

div({className:"container"}, [<br>button({text: "+", onClick: () => setVolume(volume +1)}),<br>span({className: "currentVolume", text: volume}),<br>button({text: "-", onClick: () => setVolume(volume -1)}),<br>]) ">import {div, button, span} from './vanilla-fp.js'<br>export const VolumeControl = ({volume = 0, setVolume}) =><br>div({className:"container"}, [<br>button({text: "+", onClick: () => setVolume(volume +1)}),<br>span({className: "currentVolume", text: volume}),<br>button({text: "-", onClick: () => setVolume(volume -1)}),<br>])

Each vanilla-fp , a component is in charge of keeping the states of its children, instead of utilizing some external global functions and frameworks. It does so by calling it's own 'setState' function and saving the child state in the component's own state.

div({},[<br>span({text:userInfo.name}),<br>VolumeControl({<br>volume: userInfo.credits,<br>setVolume: (volume) => setUserInfo({...userInfo, credits: volume})<br>})<br>])">import {VolumeControl} from './volume-control.js'<br>import {span ,div, button} from './vanilla-fp.js'

export const UserEdit = ({userInfo, setUserInfo}) =><br>div({},[<br>span({text:userInfo.name}),<br>VolumeControl({<br>volume: userInfo.credits,<br>setVolume: (volume) => setUserInfo({...userInfo, credits: volume})<br>})<br>])

But what's at the root of the tree? There can be many options. The reference implementation, which just replaces the DOM elements actually works rather well.

console.log('Rendering app with state', state)<br>document.getElementById("vanilla-fp")<br>.replaceChildren(component({<br>state,<br>setState: (state) => renderComponent(component, state, params),<br>fetch,<br>...params<br>}))<br>}">export const renderComponent = (component, state = {}, params) => {<br>console.log('Rendering app with state', state)<br>document.getElementById("vanilla-fp")<br>.replaceChildren(component({<br>state,<br>setState: (state) => renderComponent(component, state, params),<br>fetch,<br>...params<br>}))

Why?

Using component-based design allows you to organize your stuff better by promoting hierarchy in your code . However, it is rarely utilized to the fullest, because of the lack of a standard way of managing state when developing components (in most cases you have to have a global variable in your program, but we have to at least make sure it is just one global variable.

"Why not just Redux/MobX?"

Redux is great, but it only handles state, so a component would have to come in two parts - state handler and template - that you have to assemble every time. Because of this, Redux is not composable e.g. there is no standard way of embedding one Redux app into another. There is no such thing as a Redux component.

"Why not React useState?"

useState is not great IMO, for many reasons:

You neither have control, nor visibility of the states of your child components. which provokes endless SO debates on "How to listen to child component events", "How to change the state of the child component" etc. Encapsulation of state is important but when you have a hierarchy, the parent has to always have access to the children's state.

The...

state component volume vanilla text framework

Related Articles