React on λambda


Without special ceremonies, we will start distributing bream and shouting about functionalism, and by the way, hello everyone!


With development, the reagent smoothly gets rid of OOP impurity and more and more approaches functional programming. In the beginning, higher-order components (HOC) appeared in it instead of mixins, then stateless components were almost a substitute for classes, and here's the last jerk, rolled out hooks that completely relieve the class of reacts.


I don’t know where the next branch of development will lead, but I can confidently say it’s time to get rid of JSX already, and yes in favor of those very functions. If Sergey Druzhko had been with us, we would have heard:


- A strong statement, I certainly will not check it .


But I invite you to check it, or rather to estimate what a reaction can be without JSX.



Kingdom of the patterns


In the world of templates, everything revolves around his majesty the text, you plunge into it to the ears and proceed to dirty business, namely, insert the code, indicating where to repeat, and where to show or hide something. And to indicate the border between the text and the code, antennae (curly braces), tags or some other directives are used.




Unlike template engines, in JSX, the transition from code to HTML occurs automatically without markup and these transitions can be repeated recursively. That is why you can hear criticism towards JSX, saying that you are encoding JS inside HTML, and inside that JS is another embedded HTML, etc.


Well, for the rest, JSX is the same template engine, but all because initially the XHP influenced the reaction , in fact it is a PHP tuned Facebook. If pure reactivity is small, which has something to do with XHP, then JSX is his twin brother, but only in the JavaScript world.


There is nothing wrong with templating, on the contrary it is a very convenient tool for working with text. However, for component development, functions are the most appropriate tool. A logical question may arise: how can functions simplify work on the text?


After all, now you get HTML + CSS from the layout / designer, quickly inserted the antennae or directives there, and the component is ready, or even look at the whole page. Yes, certainly here frameworks like Vue / Angular are taxiing out and our reaction was quietly crying aside. Unfortunately, in practice I have never met a designer who provided HTML + CSS, and the typesetter was a mythical character that no one had ever met in life, and in the life of many companies, even designers on staff are fictional creatures, and all this work is done , right - the front-end. That is why often in job requirements we come across the following:


- Experience on Bootstrap eighth version for at least 10 years.


If this is your case, then there is no difference there: typesetting at the beginning of HTML with antennae or immediately bambling components on pure functions. Although, of course, there is a difference with the functions, you will have to tap less on the keys.


Kingdom functions


Most likely you already guess that in this world His Majesty will rule the function, and all around there will be functions, now the components are functions, tags are also functions, in this kingdom discrimination will affect even variables, and again in favor of functions. Total racism.


However, in this world not all functions are equal, there are the usual functions of mongrels, and there are nobles - curried functions , apparently Sir Curry Haskell himself granted him this title.


Further in the examples, I will use the react-on-lambda library from a certain author - me, but nothing prevents you from creating your own bike.


Ok, let's look at these nobles:


import λ from 'react-on-lambda'
const postLink = λ.a({href: `/posts/123`})

At first glance, an ordinary function, but there is a characteristic feature, postLink is not yet an HTML element or even a react element, but a function in which you can stuff it with props and it will always return the function until we pass it a child element in the form of: string, numbers, another lambda function or an empty value, and then the magic will happen, the element will be returned, which will eventually be converted to HTML.


For example, like this:


postLink(`Read more`)
// JSX equivalent
Read more

Ah, yes, the Greek letter could confuse you: λ just ignore it, you can replace it with any other identifier, for example:


import l from 'react-on-lambda'
// or 
import {div, h1} from 'react-on-lambda'

I think such quirks are not encountered for the first time in js, for us they are already like $ _ native characters , it would seem to be some connection with bucks and any for DOM manipulation. And lambda came to my taste, as it echoes the name of the lib itself.


And so, during the execution of the program, the properties of elements / components can be assembled from different pieces without resorting to global variables, and most importantly, you can build point-free compositions:


const title = λ.compose(
  λ.h1({className: `post-title`}),
  postLink
)
const post = λ.div(
  title(`How to use react on lambda?`),
  λ.p(`
    Lorem ipsum dolor sit amet,
    Ernestina Urbanski consectetur adipiscing elit.
    Ut blandit viverra diam luctus luctus...
  `),
  postLink(`Read more`)
)
render(
  post,
  document.getElementById(`app`)
)

Using composition, we created a new title function , which consists of two other functions, h1 and postLink . Passing the value to title, we get a clickable title with the text: "How to use react on lambda?". In the composition, the result from one function is transferred to another, and the data flow occurs from the bottom up.




Thanks to this feature, functions in the composition are placed without nesting. Remember the callback before Promise and async / await appeared , how they strained, and how they just didn't call them: spaghetti code, callback hell, pyramid of doom, christmas tree from hell, but for some reason multi-storey nesting in HTML does not bother anyone.


Next, we again applied postLink , but with a different parameter, so we used the function more than once. Of course, this can be done with JSX by wrapping it in a function, but then we come to the main question, or can we just use functions instead of JSX?



Kingdom React on λambda


Rather, it is not a kingdom, but a small county in the kingdom of functions. I suggest getting to know React on lambda closer :


Main features of the library:


  • the output will get the bundle size smaller , up to 20% in comparison with a similar project written in JSX;
  • no transpiler (babel) or separate webpack settings required; works directly in the browser;
  • seamless integration into an existing react project with JSX.

For a more detailed introduction, I suggest looking at the demo projects:




Creationism in RoL


To create a react element, just type:


import λ, {div} from 'react-on-lambda'
div({class: `sample`}, `Hello world!`) // you can use class instead className
// JSX equivalent
Hello world!

Properties can overlap:


const span = λ.span({class: `large`}) // -> function
span({class: `small`}, `Sorry we changed our mind`)
// JSX equivalent
Sorry we changed our mind

It is enough to wrap the existing components of λ to get the function and all the buns of the phase transition function from them.


λ(Provider, {store}, app)
// JSX equivalent

All child lambda functions will be called automatically by the parent element:


λ.div(
  λ.div({class: `followers`}),
  λ.br
)

That is, it is not necessary to call them:


λ.div(
  λ.div({class: `followers`})(),
  λ.br()
)()

This was done for convenience and ease of integration with other libraries, such as redux.


And then I will briefly introduce you to other auxiliary functions. I want to remind you that all subjects from react-on-lambda are curried functions.



λ.mapKey


The mapKey function is used to iterate over arrays.


const pages = [`Home page`, `Portfolio`, `About`]
λ.ul(
  λ.mapKey(λ.li, pages)
)
// JSX equivalent
    {pages.map((item, key) =>
  • {item}
  • )}

Вставка ключа (key) будет автоматической и будет равна индексу элемента из массива. Автоматическая вставка ключа будет только если не был передан ключ.



λ.mapProps


Функция для преобразования свойств объекта. Довольно спорная функция, ее можно получить из других сторонних библиотек, но я решил ее оставить.


const data = [
  {id: 123, name: `Albert`, surname: `Einstein`},
  {id: 124, name: `Daimaou `, surname: `Kosaka`},
]
const userList = λ.compose(
  λ.div({class: `followers`}),
  λ.ul,
  λ.mapKey(λ.li),
  λ.mapProps({key: `id`, children: `name`})
)
userList(data)
// JSX equivalent
const UserList = props => (
  
    {props.data.map(user =>
  • {user.name}
  • )}
)


λ.log


Функция для отладки:


const userList = λ.compose(
  λ.div,
  λ.ul,
  λ.log(`after mapping`), // -> will log piping value
  λ.mapKey(λ.li)
)

Стилизация компонентов


Для любителей styled-components, есть встроенная обертка, которая возвращает стилизованный компонент в виде функции:


import λ from 'react-on-lambda'
const header = λ.h1`
  color: #ff813f;
  font-size: 22px;
`
const onClick = () => alert(`Hi!`)
const app = λ.div(
  header(`Welcome to React on λamda!`),
  λ.button({onClick}, `OK`)
)

Я намерено не стал пичкать библиотеку другим функционалом, так как множество фишек можно получить из библиотек: ramda, rambda, lodash/fp.


Ну на этом всё, буду рад вашим отзывам.



Берегите себя, да пребудет с вами святой функтор!


Also popular now: