Logo

dev-resources.site

for different kinds of informations.

Understanding Hooks in the Phoenix Framework

Published at
9/30/2024
Categories
elixir
webdev
javascript
hook
Author
rushikeshpandit
Categories
4 categories in total
elixir
open
webdev
open
javascript
open
hook
open
Author
15 person written this
rushikeshpandit
open
Understanding Hooks in the Phoenix Framework

Hello everyone,

I hope this message finds you in good spirits. In the current piece, we will focus our attention on the concept of hooks in the Phoneix app.

Phoenix Framework Hooks are a great extension of LiveView improvements by executing custom JavaScript on the client side. It enables you to use JavaScript directly, which isnโ€™t feasible or efficient only with live view, where there is a need for dynamic behaviour.

In the Phoenix Framework context, hooks are simply a method that allows triggering JavaScript when a given element of the LiveView is rendered or updated in the DOM.

Hooks help in smoothly adding any form of interaction with the LiveView that is already painted on the browser. Most of the interaction with Phoenix LiveView is that the contents are rendered on the server side. However, there are cases such as when the UI is animated, or some other javascript library is turning up that some actions on the front end have to take place in real-time to perform certain actions on the user interface.

Importantly, while Phoenix LiveView efficiently handles state and UI updates from the server, there are cases when client-side code is required. For example:

  • Third-Party Libraries: Imagine you're integrating a charting library like Chart.js or a UI toolkit that requires client-side code to initialise after a LiveView page is loaded.

  • Custom DOM Manipulation: Sometimes, you need to apply JavaScript directly to an element after it's rendered.

  • Animations: There are cases where animations triggered by JavaScript can enhance the user experience, such as sliding in a notification bar or creating modal popups.

  • Handling Real-Time Events: For real-time event handling beyond what Phoenix Channels or LiveView directly provide, you may need JavaScript to react to specific events in the front end.

With the introduction of Hooks, it has become possible to enhance client-side functionalities without losing the merits of server-side rendered pages.

Adding Support For Hooks To Phoenix

Hooks primarily are instantiated in the LiveSocket object in JavaScript. In your LiveView templates, you include hooks to certain elements and every time that element gets rendered or is updated, that hook will run its Javascript code.

Step 1: Define the Hook in JavaScript

To get started, create a hook in a javascript file that is prepared to cover LiveView features.

Usually, the importation of the LiveSocket and the initialisation of the custom hooks are found in the โ€˜assets/js/app.jsโ€™ file in Phoenix.
Hereโ€™s how you can define a simple hook:

let Hooks = {};

Hooks.ExampleHook = {
  mounted() {
    console.log("Hook mounted!");
    // Your logic when the hook is attached to an element
  },
  updated() {
    console.log("Hook updated!");
    // Logic when the DOM updates with this element
  },
  destroyed() {
    console.log("Hook destroyed!");
    // Cleanup logic when the element is removed
  }
};

let liveSocket = new LiveSocket("/live", Socket, {
  hooks: Hooks
});

liveSocket.connect();
Enter fullscreen mode Exit fullscreen mode

This example defines a hook named ExampleHook that can respond to lifecycle events such as mounted(), updated(), and destroyed().

  • mounted(): Executes when the element is first rendered.
  • updated(): Executes when the element updates (such as when LiveView re-renders).
  • destroyed(): Executes when the element is removed from the DOM.

Step 2: Use the Hook in Your LiveView Template

After defining your hook in JavaScript, you need to attach it to an element in your LiveView template. You can do this using the phx-hook attribute.

<div id="example" phx-hook="ExampleHook">
  <!-- Your dynamic content goes here -->
</div>
Enter fullscreen mode Exit fullscreen mode

The phx-hook attribute connects the HTML element to the ExampleHook you defined in JavaScript. When this element is rendered or updated by LiveView, the appropriate JavaScript lifecycle methods (e.g., mounted, updated, etc.) will be triggered.

Step 3: Add Custom Behavior

Letโ€™s add some custom behaviour to the hook to demonstrate its capabilities. For example, let's say you want to focus an input field as soon as it is mounted:

Hooks.FocusInput = {
  mounted() {
    this.el.focus();
  },
  updated() {
    this.el.focus();
  }
};
Enter fullscreen mode Exit fullscreen mode

This FocusInput hook will focus the input field whenever it is mounted or updated.

Now, attach this hook to your LiveView template:

<input type="text" phx-hook="FocusInput" placeholder="Focus me!">
Enter fullscreen mode Exit fullscreen mode

When this input field is rendered, it will automatically receive focus, creating a smooth user experience.

Implementing a Chart.js Hook

For a more advanced example, use hooks to integrate a charting library such as Chart.js into a LiveView page.

Step 1: Define the Hook in app.js.

Hooks.Chart = {
  mounted() {
    let ctx = this.el.getContext('2d');
    this.chart = new Chart(ctx, {
      type: 'bar',
      data: {
        labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
        datasets: [{
          label: '# of Votes',
          data: [12, 19, 3, 5, 2, 3],
          backgroundColor: 'rgba(255, 99, 132, 0.2)',
          borderColor: 'rgba(255, 99, 132, 1)',
          borderWidth: 1
        }]
      },
      options: {
        scales: {
          y: {
            beginAtZero: true
          }
        }
      }
    });
  },
  updated() {
    this.chart.update();
  },
  destroyed() {
    this.chart.destroy();
  }
};
Enter fullscreen mode Exit fullscreen mode

Step 2: Attach the Hook in Your Template

<canvas id="myChart" phx-hook="Chart" width="400" height="400"></canvas>
Enter fullscreen mode Exit fullscreen mode

Now, whenever this canvas element is rendered by LiveView, the chart will be drawn using Chart.js.

That's it for the day. In the next part, we will go through some more concepts of the Phoenix framework.

Feel free to reach out if you need help.

LinkedIn: https://www.linkedin.com/in/rushikesh-pandit
GitHub: https://github.com/rushikeshpandit
Portfolio: https://www.rushikeshpandit.in

#myelixirstatus , #elixir , #phoenixframework

hook Article's
30 articles in total
Favicon
Share the state of a hook between components
Favicon
Understanding Hooks in the Phoenix Framework
Favicon
React Hooks: A Detailed Explanation
Favicon
Reusable React Hook Form
Favicon
Client side Git hooks 101
Favicon
React Hooks
Favicon
How not to useEffect
Favicon
Understanding useContext Hooks in React โ€“ An introduction and a Comprehensive Guide for Web Developers
Favicon
Understanding useState Hook in React โ€“ An introduction and a Comprehensive Guide for Web Developers
Favicon
Understanding useEffect Hooks in React โ€“ An introduction and Comprehensive Guide for Web Developers
Favicon
React 18 hooks
Favicon
Reusable Code: React Custom Hooks Guide
Favicon
React Usecallback for Kids/Beginners
Favicon
Optimizing Event Handlers in React using useCallback
Favicon
Understanding the useState Hook in React
Favicon
Implement refetch with axis
Favicon
Handle component state using local storage: useLocalStorage with Typescript
Favicon
Skills of writing unit test for react
Favicon
The practice of using Microsoft OAuth in the React hook
Favicon
Hooks in React
Favicon
A Guide to Building Custom Hooks in React
Favicon
A Guide to React Custom Hooks
Favicon
React Performance Booster - Introduction to the useMemo hook
Favicon
Mastering LocalStorage Management with React Hooks
Favicon
React Custom Hooks that can take props, but not always, what to do in TypeScript?
Favicon
useLocation Hook in React Router
Favicon
useLocation Hook in React Router
Favicon
Building a Custom React Hook: useIsAppOffline
Favicon
useLongPress Custom Hook
Favicon
Renderprops vs Custom Hooks: Which one to use?

Featured ones: