Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 3708

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 61k
Author
Asked: November 26, 20242024-11-26T05:14:10+00:00 2024-11-26T05:14:10+00:00

React Gets Svelte Flavoured Drag and Drop (or Svelte Actions via React Hooks)

  • 61k

TLDR: Check out the brand new library: react-dnd-action. It brings the leading drag and drop library for Svelte into React land, and mimics Svelte's “action” pattern using a custom hook. If you are interested in drag and drop or in how Svelte actions and React hooks relate to each other, continue reading.


Comparing and contrasting features in frontend frameworks (or any two solutions for the same problem) is always an interesting exercise. I still remember first learning Svelte, which happened shortly after I really got into React hooks.
Svelte has this incredible feature called “actions” (details in the official tutorial here and here).
It seems like a benign feature at first glance, but in fact it allows for amazingly elegant abstractions. For example, in the second link above you would see the longpress action. One could simply import it and write code that looks like this (a modified version of the official example for clarity):

<button use:longpress={duration}     on:pressed={doSomethingInteresting}>     Press and hold </button> 
Enter fullscreen mode Exit fullscreen mode

and magic… the logic for detecting long presses is fully encapsulated and abstracted away. How elegant and reusable is that?
Keen eyed React developers have probably noticed the prefix use: and recalled React hooks, which curiously use (pun intended) the same convention. Are Svelte actions and React hooks alike?

Svelte action vs. React hook

What is an action in Svelte?

The power of Svelte actions (and what makes them a unique pattern) comes from the fact that they operate outside of Svelte. You cannot use Svelte's reactivity or any of its normal syntax when implementing an action. You only have Javascript at your disposal. If you implement the API that Svelte defines for actions, you will get seamless integration with any Svelte application; but the framework doesn't impose any of its normal limitations on your code.
This may sound like a drawback or a strange design decision, but it is any library author/ tools maker's dream come true. The consumers of the library get to have all of the syntactic elegance and power that Svelte offers. The library author gets the thing they want and can leverage the most: full control and direct access to the underlying platform.
What is the API that Svelte defines for actions and that allows this win-win situation? I'm glad you asked.

  • An action is a vanilla Javascript function that takes two parameters: a DOM node to attach to, and optionally an object of options, which can include any set of properties.
  • The function can return an object with two other functions: update(options) and destroy(), which are invoked by Svelte when the options change (update) and when the host element is removed (destroy). Note that the action function is not re-run whenever the options change, only the update function gets called.
  • When the action wants to communicate with the host component, it is expected to dispatch custom events (in the code snippet above the event is called pressed). It is worth noting that even dispatching the events is done in a Vanilla way, not in the “Svelte way”.

All of the above means that the action code does not depend on Svelte code whatsoever. It is just vanilla code that respects Svelte's contract for actions.

What is a hook in React?

Hooks are also functions, but unlike actions they live within the scope of React and its rendering cycle, and have access to its constructs (mostly other hooks).

  • A hook function can take any list of arguments.
  • A hook can return any value. When it returns a value, it triggers a reevaluation (re-render) of its parent component/hook. In other words, it communicates with its parent via re-running itself (which can be initiated in several ways) and returning a value.
  • When the parent element/hook re-evaluates, the entire hook function is re-executed with a fresh list of parameters. The same is true when the hook internal state is changed via setState.
  • If the hook needs to seperate initialisation logic from update logic or have different things happen in different times, built-in hooks like useRef, useMemo and useCallback are typically used.

The power of hooks comes from not being tied to the components tree. They are reusable pieces of potentially stateful and effect-full logic that work within the rendering cycle without committing to any hierarchy (unlike abstractions like higher order components for example).


We can see that a React hook is less specific in its API than a Svelte action. On the other hand, a Svelte action is less framework specific and imposes less limitations on its author.
To be fair, I am comparing apples and oranges. These are solutions to different problems: Hooks solve a general problem while actions are focused on augmenting DOM element with custom functionality.

Can A React Hook Behave Like a Svelte Action?

Since hooks are more generic than actions and assuming we are willing to give up some of Svelte's syntactic sugar, the answer would have to be yes. Let's define what a React Action might look like:

  • It is a custom hook with no return value.
  • It takes in a ref to a Dom node and an options object just like its Svelte counterpart.
  • Instead of dispatching events (which doesn't play well with React conventions or with its synthetic events system), it can accept the event-handlers as additional arguments.

This kind of hook might offer the same great developer experience that Svelte provides with its actions.
This sounds nice in theory but can it work in practice?
I wrote react-dnd-action in order to find out. All it is made of is:

  1. A custom hook that acts as an adapter for svelte-dnd-action.
  2. A flip utility to compensate for the lack of built-in flip in React.

Drag and Drop via a React “Action”

Here is what a generic “vertical or horizontal list with draggable items” looks like when using a “react action”:

import React, { useRef } from "react"; import { useDndZone } from "react-dnd-action";  export function List({ items, onItemsChange, isHorizontal = false }) {   const listRef = useRef();   useDndZone(listRef, { items }, ({ items: newItems }) =>     onItemsChange(newItems)   );    return (     <ul className={isHorizontal ? "list horizontal" : "list"} ref={listRef}>       {items.map((item) => (         <li key={item.id}>{item.id}</li>       ))}     </ul>   ); }  
Enter fullscreen mode Exit fullscreen mode

The call to useDndZone is where the magic happens.
As we said above, it takes a ref to the container we would like to turn into a dnd zone, an object with options (in this case just the list of items data) and a callback that is updating the list of items every time a dnd event takes place.
You can play with it in codesandbox:

Not sure what you think, but I think it is quite expressive and nice.

How about a Trello-like board with draggable columns and items?

There are more examples in the README.


Even though it is a brand new library it is feature rich because it leverages everything that svelte-dnd-action has to offer.
Did I mention it supports touch and keyboard, scrolling containers and is accessible out of the box? Oh and it's only 8.5kb minified and gzipped.

Summary and Current Status

At the time of writing these lines, react-dnd-action is ready to be used but still experimental.
I have no intentions of making breaking changes to the API. There is bunch of work that still needs to be done (contributions are welcome btw): Adding examples, adding typescript type definitions, polishing out little quirks, cleaning up the logs etc.
The reason I am releasing it now is because this is an excellent time to get your feedback and thoughts.
Would you find this flavour of drag and drop useful?
What do you think about “actions” in React? Is it a pattern that makes sense to you?
Thanks for reading and happy dragging and dropping.

javascriptreactsveltewebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 1k
  • Popular
  • Answers
  • Author

    How to ensure that all the routes on my Symfony ...

    • 0 Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.