Gathering detailed insights and metrics for react-sortablejs-typescript
Gathering detailed insights and metrics for react-sortablejs-typescript
Gathering detailed insights and metrics for react-sortablejs-typescript
Gathering detailed insights and metrics for react-sortablejs-typescript
@snapdrag/react
React hooks for Snapdrag drag and drop library
snapdrag
A simple, lightweight, and performant drag and drop library for React and vanilla JS
snapdrag-beta
A simple, lightweight, and performant drag and drop library for React and vanilla JS
@snapdrag/core
Core logic for Snapdrag drag and drop library
npm install react-sortablejs-typescript
Typescript
Module System
Cumulative downloads
Total Downloads
Last Day
-50%
2
Compared to previous day
Last Week
-62.5%
33
Compared to previous week
Last Month
48.7%
235
Compared to previous month
Last Year
-40.7%
18,765
Compared to previous year
2
22
react-sortablejs-typescript
React component wrapping SortableJS written in Typescript!
Everything you love about SortableJS, including to but not limited to:
props
. Feels more like react than ever before.If you find any features lacking, create an issue and/or pull request.
1npm install --save react-sortablejs-typescript 2# OR 3yarn add react-sortablejs-typescript
1import React, { FC, useState } from "react"; 2import { ReactSortable } from "react-sortablejs-typescript"; 3 4interface ItemType { 5 id: number; 6 name: string; 7} 8 9export const BasicFunction: FC = props => { 10 const [state, setState] = useState<ItemType[]>([ 11 { id: 1, name: "shrek" }, 12 { id: 2, name: "fiona" } 13 ]); 14 15 return ( 16 <ReactSortable list={state} setList={setState}> 17 {state.map(item => ( 18 <div key={item.id}>{item.name}</div> 19 ))} 20 </ReactSortable> 21 ); 22};
1import React, { Component } from "react"; 2import { ReactSortable } from "react-sortablejs-typescript"; 3 4interface BasicClassState { 5 list: { id: string; name: string }[]; 6} 7 8export class BasicClass extends Component<{}, BasicClassState> { 9 state: BasicClassState = { 10 list: [{ id: "1", name: "shrek" }] 11 }; 12 render() { 13 return ( 14 <ReactSortable 15 list={this.state.list} 16 setList={newState => this.setState({ list: newState })} 17 > 18 {this.state.list.map(item => ( 19 <div key={item.id}>{item.name}</div> 20 ))} 21 </ReactSortable> 22 ); 23 } 24}
div
as the parent by default.ReactSortable is a div
element by default. This can be changed to be any HTML element (for example ul
, ol
)
or can be a React component.
This value, be the component or the HTML element should be passed down under props.tag
.
Let's explore both here.
Here we will use a ul
. You can use any HTML.
Just add the string and ReactSortable will use a li
instead of a div
.
1import React, { FC, useState, forwardRef } from "react"; 2import { ReactSortable } from "react-sortablejs-typescript"; 3 4interface ItemType { 5 id: string; 6 name: string; 7} 8 9export const BasicFunction: FC = props => { 10 const [state, setState] = useState<ItemType[]>([{ id: "1", name: "shrek" }]); 11 12 return ( 13 <ReactSortable tag="ul" list={state} setList={setState}> 14 {state.map(item => ( 15 <div key={item.id}>{item.name}</div> 16 ))} 17 </ReactSortable> 18 ); 19};
When using a custom component in the tag
prop, the only component it allows is a forwardRef
component.
If it doesn't have one, you can add one using React.forwardRef()
.
This fantastic API allows the ref to be visible when creating components.
Use this when third party UI libraries.
NOTE: You may experience inconsistencies with this until we launch the proper version.
todo: Some third party UI components may have nested elements to create the look they're after. This could be an issue and not sure how to fix.
1import React, { FC, useState, forwardRef } from "react"; 2import { ReactSortable } from "react-sortablejs-typescript"; 3 4interface ItemType { 5 id: string; 6 name: string; 7} 8 9// This is just like a normal component, but the 10const CustomComponent = forwardRef<HTMLDivElement, any>((props, ref) => { 11 return <div ref={ref}>{props.children}</div>; 12}); 13 14export const BasicFunction: FC = props => { 15 const [state, setState] = useState<ItemType[]>([ 16 { id: 1, name: "shrek" }, 17 { id: 2, name: "fiona" } 18 ]); 19 20 return ( 21 <ReactSortable tag={CustomComponent} list={state} setList={setState}> 22 {state.map(item => ( 23 <div key={item.id}>{item.name}</div> 24 ))} 25 </ReactSortable> 26 ); 27};
Sortable affects the DOM, adding, and removing nodes/css when it needs to in order to achieve the smooth transitions we all know an love. This component reverses many of it's actions of the DOM so React can handle this when the state changes.
key !== index
DO NOT use the index as a key for your list items. Sorting will not work.
In all the examples above, I used an object with an ID. You should do the same!
I may even enforce this into the design to eliminate errors.
setState()
setState
takes one argument only. If we look in the type defs, it does say that it has a second argument, but it is already deprecated. ReactSortable passes three arguments to setState
.
If you pass the setState
straight from a useState
hook, it will work as expected. However, there will be a warning in the console:
Warning: State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect().
It's just a warning and there's nothing to worry about. Nothing will break if you leave the messages there.
1import React, { FC, useState } from "react"; 2import { ReactSortable } from "react-sortablejs-typescript"; 3 4interface ItemType { 5 id: string; 6 name: string; 7} 8 9export const BasicFunction: FC = props => { 10 const [state, setState] = useState<ItemType[]>([{ id: "1", name: "shrek" }]); 11 12 return ( 13 <ReactSortable 14 list={state} 15 // will cause warnings in dev mode only. 16 setList={setState} 17 > 18 {state.map(item => ( 19 <div key={item.id}>{item.name}</div> 20 ))} 21 </ReactSortable> 22 ); 23};
This is just a warning, but can be annoying when developing.
Instead of passing setState
in directly, be explicit in your callback:
1import React, { FC, useState } from "react"; 2import { ReactSortable } from "react-sortablejs-typescript"; 3 4interface ItemType { 5 id: string; 6 name: string; 7} 8 9export const BasicFunction: FC = props => { 10 const [state, setState] = useState<ItemType[]>([{ id: "1", name: "shrek" }]); 11 12 return ( 13 // `sortable` and `store` arguments are here just to show what arguments have been passed. 14 // They are not required to be used and you shouldn't really need them. 15 <ReactSortable 16 list={state} 17 // will not cause warnings in dev mode only. 18 setList={(newState, sortable, store) => setState(newState)} 19 > 20 {state.map(item => ( 21 <div key={item.id}>{item.name}</div> 22 ))} 23 </ReactSortable> 24 ); 25};
Basically the child updates the state twice. I'm working on this.
Our usage indicates that as long as we only move items between lists that don't use the same setState
function.
I hope to provide an example soon.
We don't have anything that works 100%, but here I'd like to spit ball some potential avenues to look down.
onMove
to handle state changes instead of onAdd
,onRemove
, etc.No vulnerabilities found.
No security vulnerabilities found.