I am using the react-sortable-hoc package and want to use it in a functional component instead. I have tried to convert it but there is a line that is giving me an error.
The list shows up and I can drag any element but as soon as I drop it I get the error
Cannot read property 'slice' of undefined
It looks as if it is posting to this line:
items: arrayMove(items, oldIndex, newIndex),
Here is the class based version:
import React, {Component} from 'react';
import {render} from 'react-dom';
import {sortableContainer, sortableElement} from 'react-sortable-hoc';
import arrayMove from 'array-move';
const SortableItem = sortableElement(({value}) => <li>{value}</li>);
const SortableContainer = sortableContainer(({children}) => {
return <ul>{children}</ul>;
});
class App extends Component {
state = {
items: ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6'],
};
onSortEnd = ({oldIndex, newIndex}) => {
this.setState(({items}) => ({
items: arrayMove(items, oldIndex, newIndex),
}));
};
render() {
const {items} = this.state;
return (
<SortableContainer onSortEnd={this.onSortEnd}>
{items.map((value, index) => (
<SortableItem key={`item-${value}`} index={index} value={value} />
))}
</SortableContainer>
);
}
}
render(<App />, document.getElementById('root'));
And the version I am trying to put together:
import React, { useState } from "react";
import { sortableContainer, sortableElement } from "react-sortable-hoc";
import arrayMove from "array-move";
const SortableItem = sortableElement(({ value }) => <li>{value}</li>);
const SortableContainer = sortableContainer(({ children }) => {
return <ul>{children}</ul>;
});
const Dashboard = () => {
const [items, setItems] = useState([
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5",
"Item 6",
]);
const onSortEnd = ({ oldIndex, newIndex }) => {
setItems(({ items }) => ({
items: arrayMove(items, oldIndex, newIndex),
}));
};
return (
<SortableContainer onSortEnd={onSortEnd}>
{items.map((value, index) => (
<SortableItem key={`item-${value}`} index={index} value={value} />
))}
</SortableContainer>
);
};
export default Dashboard;
You need not destructure items
from setItems
callback as state doesn't store the object in your case but an array. Also you must not set the value back as an object, instead it should be an array again
setItems((items) => arrayMove(items, oldIndex, newIndex));