Languages
[Edit]
EN

React - useArray() hook as alternative to useState() with array

0 points
Created by:
chelsea
806

In this article, we would like to show you useArray() hook as an alternative to useState() in JavaScript.

Quick solution:

// Read more here:  https://dirask.com/snippets/jmJNN1
//
const useProxy = (action) => {
    const state = React.useMemo(
        () => ({
            wrapper: (...args) => {
                if (state.action) {
                    return state.action(...args);
                }
                return undefined;
            }
        }),
        []
    );
    state.action = action;
    return state.wrapper;
};

// ----------------------

// Read more here:  https://dirask.com/snippets/D7XEop

const prependItem = (updater, item) => {
    updater(array => [].concat(item, array));
};

const appendItem = (updater, item) => {
    updater(array => [].concat(array, item));
};
  
const replaceItem = (updater, index, item) => {
    updater(array => array.map((value, i) => i === index ? item : value));
};

const removeItem = (updater, index) => {
    updater(array => array.filter((value, i) => i !== index));
};

// ----------------------

const useArray = (initialArray = []) => {
    const [items, setItems] = React.useState(initialArray);
    return {
        getItems:    useProxy(()            => items),
        setItems:    useProxy((items)       => setItems(items)),
        prependItem: useProxy((item)        => prependItem(setItems, item)),
        appendItem:  useProxy((item)        => appendItem(setItems, item)),
        replaceItem: useProxy((index, item) => replaceItem(setItems, index, item)),
        removeItem:  useProxy((index, item) => removeItem(setItems, index)),
        isEmpty:     useProxy(()            => items.length === 0),
    };
};


// Usage example:

const App = () => {
    const array = useArray([]);
/*
    const items = array.getItems();         // returns array with items

    array.setItems(['a', 'b', 'c']);        // replaces all array with new one
    array.prependItem('prepended item');    // ads new item to the array beginning
    array.appendItem('appended  item');     // ads new item to the array ending
    array.replaceItem(1, 'replaced item');  // replaces item that has index 1 to new one
    array.removeItem(1);                    // removes item that has index 1
*/

    ...
};

 

Practical example

In this example, we present how to create and use useArray() hook as an alternative to the useState(). We also use useProxy() custom hook to wrap functions so they always have the same reference.

// ONLINE-RUNNER:browser;

// Read more here:  https://dirask.com/snippets/jmJNN1
//
const useProxy = (action) => {
    const state = React.useMemo(
        () => ({
            wrapper: (...args) => {
                if (state.action) {
                    return state.action(...args);
                }
                return undefined;
            }
        }),
        []
    );
    state.action = action;
    return state.wrapper;
};

// ----------------------

// Read more here:  https://dirask.com/snippets/D7XEop

const prependItem = (updater, item) => {
    updater(array => [].concat(item, array));
};

const appendItem = (updater, item) => {
    updater(array => [].concat(array, item));
};
  
const replaceItem = (updater, index, item) => {
    updater(array => array.map((value, i) => i === index ? item : value));
};

const removeItem = (updater, index) => {
    updater(array => array.filter((value, i) => i !== index));
};

// ----------------------

const useArray = (initialArray = []) => {
    const [items, setItems] = React.useState(initialArray);
    return {
        getItems:    useProxy(()            => items),
        setItems:    useProxy((items)       => setItems(items)),
        prependItem: useProxy((item)        => prependItem(setItems, item)),
        appendItem:  useProxy((item)        => appendItem(setItems, item)),
        replaceItem: useProxy((index, item) => replaceItem(setItems, index, item)),
        removeItem:  useProxy((index, item) => removeItem(setItems, index)),
        isEmpty:     useProxy(()            => items.length === 0),
    };
};

// ----------------------


// Usage example:

let counter = 0;

const App = () => {
    const array = useArray([]);
    const handlePrependClick = () => {
        array.prependItem((++counter) + '-prepended');
    };
    const handleAppendedClick = () => {
        array.appendItem((++counter) + '-appended ');
    };
    const items = array.getItems();
    return (
        <div>
          <div>
            <button onClick={handlePrependClick}>Prepend</button>
          </div>
          <br />
          <pre style={{border: '1px solid silver'}}>
            {items.map((item, index) => {
                const handleReplaceClick = () => {
                    array.replaceItem(index, (++counter) + '-replaced ');
                };
                const handleRemoveClick = () => {
                    array.removeItem(index);
                };
                return (
                    <div key={item}>
                      <span>{item}</span>
                      {' '}
                      <button onClick={handleReplaceClick}>Replace</button>
                      <button onClick={handleRemoveClick}>Remove</button>
                    </div>
                );
            })}  
          </pre>
          <br />
          <div>
            <button onClick={handleAppendedClick}>Append</button>
          </div>
        </div >
    );
};

const root = document.querySelector('#root');
ReactDOM.render(<App />, root );

References

  1. Using the State Hook – React
  2. Array.prototype.concat() - JavaScript | MDN
  3. Array.prototype.map() - JavaScript | MDN
  4. Array.prototype.filter() - JavaScript | MDN
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join