useListState
useListState manages state for an immutable list data structure, and provides various methods to safely update the data over time.
| Install | yarn add @diallink-corp/convergo-state-data |
|---|---|
| Version | 4.1.2 |
| Usage | import {useListState} from '@diallink-corp/convergo-state-data' |
API
Insert API here.
Features
- Build immutable list data structures.
- Insert, prepend and append items to the list.
- Move items within a list to a new position.
- Update specific items in the list.
- Allow React to detect the "diff" between re-renders correctly.
- Narrow down the result through a search filter.
Synergy
- To render an accessible list of selectable items use a ListBox component.
Generate a List
To generate a new list you need to pass in an initial set of items to the useListState hook. Additionally,
you need to supply a getKey method, which is used as a getter method to retrieve a unique key for each
item in the list.
You can then use the items that are being returned by the useListState hook to render a collection of items.
function Example() {
const list = useListState({
initialItems: [{name: 'Penguin'}, {name: 'Unicon'}, {name: 'Dog'}],
initialSelectedKeys: ['Unicon'],
getKey: (item) => item.name
});
return (
<div>
{list.items.map((item) => (
<div key={item.name}>{item.name}</div>
))}
</div>
)
}
function Example() {
const list = useListState({
initialItems: [
{ name: 'Penguin' },
{ name: 'Unicon' },
{ name: 'Dog' }
],
initialSelectedKeys: ['Unicon'],
getKey: (item) => item.name
});
return (
<div>
{list.items.map((item) => (
<div key={item.name}>{item.name}</div>
))}
</div>
);
}
function Example() {
const list =
useListState({
initialItems: [{
name: 'Penguin'
}, {
name: 'Unicon'
}, {
name: 'Dog'
}],
initialSelectedKeys:
['Unicon'],
getKey: (item) =>
item.name
});
return (
<div>
{list.items.map((
item
) => (
<div
key={item.name}
>
{item.name}
</div>
))}
</div>
);
}
Insert Items
You can insert new items into the list with several of the methods that are being returned by the useListState hook. Each of these methods support inserting one or several items at once.
// Insert a new item after the first one.
list.insertItem(1, {name: 'Panda'});
// Insert multiple new items after the first one.
list.insertItem(1, {name: 'Panda'}, {name: 'Giraffe'});
// Insert a new item after the first one.
list.insertItem(1, {name: 'Panda'});
// Insert multiple new items after the first one.
list.insertItem(1, {name: 'Panda'}, {name: 'Giraffe'});
// Insert a new item after the first one.
list.insertItem(1, {
name: 'Panda'
});
// Insert multiple new items after the first one.
list.insertItem(1, {
name: 'Panda'
}, { name: 'Giraffe' });
// Insert a new item before another item.
list.insertItemBefore('Unicon', {name: 'Panda'});
// Insert multiple new items before another item.
list.insertItemBefore('Unicon', {name: 'Panda'}, {name: 'Giraffe'});
// Insert a new item before another item.
list.insertItemBefore('Unicon', { name: 'Panda' });
// Insert multiple new items before another item.
list.insertItemBefore('Unicon', { name: 'Panda' }, {
name: 'Giraffe'
});
// Insert a new item before another item.
list.insertItemBefore(
'Unicon',
{ name: 'Panda' }
);
// Insert multiple new items before another item.
list.insertItemBefore(
'Unicon',
{ name: 'Panda' },
{ name: 'Giraffe' }
);
// Insert a new item after another item.
list.insertItemAfter('Unicon', {name: 'Panda'});
// Insert multiple new items after another item.
list.insertItemAfter('Unicon', {name: 'Panda'}, {name: 'Giraffe'});
// Insert a new item after another item.
list.insertItemAfter('Unicon', { name: 'Panda' });
// Insert multiple new items after another item.
list.insertItemAfter('Unicon', { name: 'Panda' }, {
name: 'Giraffe'
});
// Insert a new item after another item.
list.insertItemAfter(
'Unicon',
{ name: 'Panda' }
);
// Insert multiple new items after another item.
list.insertItemAfter(
'Unicon',
{ name: 'Panda' },
{ name: 'Giraffe' }
);
// Append a new item to the start of the list.
list.appendItem({name: 'Panda'});
// Append multiple items to the start of the list.
list.appendItem({name: 'Panda'}, {name: 'Giraffe'});
// Append a new item to the start of the list.
list.appendItem({name: 'Panda'});
// Append multiple items to the start of the list.
list.appendItem({name: 'Panda'}, {name: 'Giraffe'});
// Append a new item to the start of the list.
list.appendItem({
name: 'Panda'
});
// Append multiple items to the start of the list.
list.appendItem({
name: 'Panda'
}, { name: 'Giraffe' });
// Prepend a new item to the end of the list.
list.prependItem({name: 'Panda'});
// Prepend multiple items to the end of the list.
list.prependItem({name: 'Panda'}, {name: 'Giraffe'});
// Prepend a new item to the end of the list.
list.prependItem({name: 'Panda'});
// Prepend multiple items to the end of the list.
list.prependItem({name: 'Panda'}, {name: 'Giraffe'});
// Prepend a new item to the end of the list.
list.prependItem({
name: 'Panda'
});
// Prepend multiple items to the end of the list.
list.prependItem({
name: 'Panda'
}, { name: 'Giraffe' });
Removing Items
Just as easy as you can insert new items to the list, you can also remove them with several of the helper methods returned by the useListState hook.
// Remove an item.
list.removeItem('Unicon');
// Remove multiple items.
list.removeItem('Unicon', 'Dog');
// Remove an item.
list.removeItem('Unicon');
// Remove multiple items.
list.removeItem('Unicon', 'Dog');
// Remove an item.
list.removeItem(
'Unicon'
);
// Remove multiple items.
list.removeItem(
'Unicon',
'Dog'
);
// Remove all selected items.
list.removeSelectedItems();
// Remove all selected items.
list.removeSelectedItems();
// Remove all selected items.
list
.removeSelectedItems();
Move Items
The useListState hook not only supports inserting and removing of items but also moving them. This can be useful if a list needs to support re-ordering or drag-n-drop.
// Move the item to the index 0.
list.moveItem('Dog', 0);
// Move the item to the index 0.
list.moveItem('Dog', 0);
// Move the item to the index 0.
list.moveItem('Dog', 0);
// Move the item before another item.
list.moveItemBefore('Dog', 'Unicorn');
// Move the item before another item.
list.moveItemBefore('Dog', 'Unicorn');
// Move the item before another item.
list.moveItemBefore(
'Dog',
'Unicorn'
);
// Move the item after another item.
list.moveItemAfter('Dog', 'Unicorn');
// Move the item after another item.
list.moveItemAfter('Dog', 'Unicorn');
// Move the item after another item.
list.moveItemAfter(
'Dog',
'Unicorn'
);
Updating Items
Additionally, the useListState hook supports updating a specific item in the list.
// Updates the item with the specified key.
list.updateItem({key: 'Dog', value: {name: 'Cute Dog'}});
// Updates the item with the specified key.
list.updateItem({key: 'Dog', value: {name: 'Cute Dog'}});
// Updates the item with the specified key.
list.updateItem({
key: 'Dog',
value: {
name: 'Cute Dog'
}
});
Settings Items
You can also replace the existing items in the list with a new set of items.
list.setItems({name: 'Panda'}, {name: 'Giraffe'});
list.setItems({name: 'Panda'}, {name: 'Giraffe'});
list.setItems({
name: 'Panda'
}, { name: 'Giraffe' });
Filtering Items
To search through the list of items and return only the matching results, you can supply a
filter and filterValue prop. The filter prop is a method, which specifies how the filter
operation based on the supplied filterValue should behave.
function Example() {
const list = useListState({
initialItems: [{name: 'Penguin'}, {name: 'Unicon'}, {name: 'Dog'}],
initialSelectedKeys: ['Unicon'],
getKey: (item) => item.name,
filter: (item, value) => item.name.includes(value)
});
return (
<div>
<div>
<label htmlFor='search'>Male</label>
<input
id='search'
name='search'
type='text'
value={list.filterValue}
onChange={(event) => list.setFilterValue(event.target.value)}
/>
</div>
{list.items.map((item) => (
<div key={item.name}>{item.name}</div>
))}
</div>
)
}
function Example() {
const list = useListState({
initialItems: [
{ name: 'Penguin' },
{ name: 'Unicon' },
{ name: 'Dog' }
],
initialSelectedKeys: ['Unicon'],
getKey: (item) => item.name,
filter: (item, value) => item.name.includes(value)
});
return (
<div>
<div>
<label htmlFor="search">Male</label>
<input
id="search"
name="search"
type="text"
value={list.filterValue}
onChange={(event) =>
list.setFilterValue(event.target.value)}
/>
</div>
{list.items.map((item) => (
<div key={item.name}>{item.name}</div>
))}
</div>
);
}
function Example() {
const list =
useListState({
initialItems: [{
name: 'Penguin'
}, {
name: 'Unicon'
}, {
name: 'Dog'
}],
initialSelectedKeys:
['Unicon'],
getKey: (item) =>
item.name,
filter: (
item,
value
) =>
item.name
.includes(
value
)
});
return (
<div>
<div>
<label htmlFor="search">
Male
</label>
<input
id="search"
name="search"
type="text"
value={list
.filterValue}
onChange={(
event
) =>
list
.setFilterValue(
event
.target
.value
)}
/>
</div>
{list.items.map((
item
) => (
<div
key={item.name}
>
{item.name}
</div>
))}
</div>
);
}