DEV Community

Simon Bundgaard-Egeberg for IT Minds

Posted on

Function components in Elixir

I have been a fan of React for a long time. I like the short, composable syntax of components, and I like that I can extract functionality into small bits and compose my UI of atoms and molecules.

Lately, I have started to find joy in creating apps and web experiences using server-side frameworks. In particular, I have used Blazor, Laravel, Lucky-Framework and Phoenix (elixir).

Of the four, the only thing that could keep my attention for a prolonged period of time was Elixir.

I cannot tell you why.

Great stuff, but what about the components?

What I missed in all the frameworks mentioned above was the single file all included React component.

And now in Phoenix Liveview 0.17 we can do that!

Let's compare React and Elixir.

Elixir

defmodule Layout do
  use Phoenix.LiveComponent

  def header_bar(assigns) do

    reversed = String.reverse(assigns.title)

    ~H"""
      <div>
        <%= reversed =>
      </div>
    """
  end
end
Enter fullscreen mode Exit fullscreen mode

React

const headerBar = (props) => {
  const reversed = props.title.split("").reverse().join("");

  return (
    <div>
      {reversed}
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

In a lot of ways, the two are the same. They are terse, self-explanatory and contained. These kind of functions can then be used for creating parts of a larger UI.

In Phoenix liveview, there are things you need to know. Since most of the work is done server-side, there are some things that will be hard to do.
Most noticeably, interacting with the DOM through JavaScript will be difficult.

There are, however, plenty of solutions to this. As an example, below I will show how to create a toggle menu in elixir as a component.

Image description

Something to notice here, is that phx-click is an annotation which tells phoenix that this is special. Earlier you would use this when you would send events back to the server to do logic and return data.

In Liveview 0.17, however, we can invoke functions directly from our module. Furthermore, it is assumed that we have created a function component that can render a menu item given some meta data.

The magic here happens in the JS.toggle call in the toggle_menu function. We use a dom selector to target the element with id menu and toggle it. All this is executed locally for the user in the dom.

References:

Phoenix Framework
Phoenix LiveView

Discussion (0)