useList<E> function

ListAction<E> useList<E>(
  1. List<E> initialList
)

Flutter state hook that manages a list with reactive updates.

Provides methods to modify a list. The component re-builds when the list changes through these methods. Direct modification of the list does not trigger re-builds.

The actions object and its methods remain stable across builds.

initialList is the starting list value.

Returns a ListAction object that provides access to the current list and all modification methods.

Example:

final listActions = useList([1, 2, 3]);

// Access the current list
print(listActions.list); // [1, 2, 3]

// Add elements
listActions.add(4);
listActions.addAll([5, 6]);

// Remove elements
listActions.remove(2);
listActions.removeAt(0);

// Modify elements
listActions.first(10);
listActions.last(20);

// Reset to initial value
listActions.reset();

Implementation

ListAction<E> useList<E>(List<E> initialList) {
  final list = useState(initialList);

  final value = useCallback<List<E> Function()>(
    () => list.value,
    const [],
  );

  final first = useCallback<void Function(E value)>(
    (value) {
      final newList = [...list.value];
      newList.first = value;
      list.value = newList;
    },
    const [],
  );

  final last = useCallback<void Function(E value)>(
    (value) {
      final newList = [...list.value];
      newList.last = value;
      list.value = newList;
    },
    const [],
  );

  final length = useCallback<int Function()>(
    () => list.value.length,
    const [],
  );

  final add = useCallback<void Function(E value)>(
    (value) {
      final newList = [...list.value];
      newList.add(value);
      list.value = newList;
    },
    const [],
  );

  final addAll = useCallback<void Function(Iterable<E> iterable)>(
    (iterable) {
      final newList = [...list.value];
      newList.addAll(iterable);
      list.value = newList;
    },
    const [],
  );

  final sort = useCallback<void Function([int Function(E, E)? compare])>(
    ([
      int Function(E, E)? compare,
    ]) {
      final newList = [...list.value];
      newList.sort(compare);
      list.value = newList;
    },
    const [],
  );

  final shuffle = useCallback<void Function([Random? random])>(
    ([random]) {
      final newList = [...list.value];
      newList.shuffle(random);
      list.value = newList;
    },
    const [],
  );

  final indexOf = useCallback<int Function(E element, [int start])>(
    (
      element, [
      start = 0,
    ]) =>
        list.value.indexOf(element, start),
    const [],
  );

  final indexWhere =
      useCallback<int Function(bool Function(E element) test, [int start])>(
    (bool Function(E element) test, [start = 0]) =>
        list.value.indexWhere(test, start),
    const [],
  );

  final lastIndexWhere =
      useCallback<int Function(bool Function(E element) test, [int? start])>(
    (bool Function(E element) test, [start]) =>
        list.value.lastIndexWhere(test, start),
    const [],
  );

  final lastIndexOf = useCallback<int Function(E element, [int? start])>(
    (element, [start]) => list.value.lastIndexOf(element, start),
    const [],
  );

  final clear = useCallback<void Function()>(
    () {
      final newList = [...list.value];
      newList.clear();
      list.value = newList;
    },
    const [],
  );

  final insert = useCallback<void Function(int index, E element)>(
    (index, element) {
      final newList = [...list.value];
      newList.insert(index, element);
      list.value = newList;
    },
    const [],
  );

  final insertAll = useCallback<void Function(int index, Iterable<E> iterable)>(
    (index, iterable) {
      final newList = [...list.value];
      newList.insertAll(index, iterable);
      list.value = newList;
    },
    const [],
  );

  final setAll = useCallback<void Function(int index, Iterable<E> iterable)>(
    (index, iterable) {
      final newList = [...list.value];
      newList.setAll(index, iterable);
      list.value = newList;
    },
    const [],
  );

  final remove = useCallback<bool Function(Object? value)>(
    (value) {
      final newList = [...list.value];
      final removed = newList.remove(value);
      list.value = newList;
      return removed;
    },
    const [],
  );

  final removeAt = useCallback<E Function(int index)>(
    (index) {
      final newList = [...list.value];
      final removed = newList.removeAt(index);
      list.value = newList;
      return removed;
    },
    const [],
  );

  final removeLast = useCallback<E Function()>(
    () {
      final newList = [...list.value];
      final removed = newList.removeLast();
      list.value = newList;
      return removed;
    },
    const [],
  );

  final removeWhere = useCallback<void Function(bool Function(E element) test)>(
    (bool Function(E element) test) {
      final newList = [...list.value];
      newList.removeWhere(test);
      list.value = newList;
    },
    const [],
  );

  final sublist = useCallback<List<E> Function(int start, [int? end])>(
    (start, [end]) => list.value.sublist(start, end),
    const [],
  );

  final getRange = useCallback<Iterable<E> Function(int start, int end)>(
    (start, end) => list.value.getRange(start, end),
    const [],
  );

  final setRange = useCallback<
      void Function(
        int start,
        int end,
        Iterable<E> iterable, [
        int skipCount,
      ])>(
    (
      start,
      end,
      iterable, [
      skipCount = 0,
    ]) {
      final newList = [...list.value];
      newList.setRange(start, end, iterable, skipCount);
      list.value = newList;
    },
    const [],
  );

  final removeRange = useCallback<void Function(int start, int end)>(
    (start, end) {
      final newList = [...list.value];
      newList.removeRange(start, end);
      list.value = newList;
    },
    const [],
  );

  final fillRange =
      useCallback<void Function(int start, int end, [E? fillValue])>(
    (start, end, [fillValue]) {
      final newList = [...list.value];
      newList.fillRange(start, end, fillValue);
      list.value = newList;
    },
    const [],
  );

  final replaceRange =
      useCallback<void Function(int start, int end, Iterable<E> iterable)>(
    (start, end, iterable) {
      final newList = [...list.value];
      newList.replaceRange(start, end, iterable);
      list.value = newList;
    },
    const [],
  );

  final asMap = useCallback<Map<int, E> Function()>(
    () => list.value.asMap(),
    const [],
  );

  final reset = useCallback(
    () {
      list.value = initialList;
    },
    const [],
  );

  final state = useRef(
    ListAction<E>(
      value,
      first,
      last,
      length,
      add,
      addAll,
      sort,
      shuffle,
      indexOf,
      indexWhere,
      lastIndexWhere,
      lastIndexOf,
      clear,
      insert,
      insertAll,
      setAll,
      remove,
      removeAt,
      removeLast,
      removeWhere,
      sublist,
      getRange,
      setRange,
      removeRange,
      fillRange,
      replaceRange,
      reset,
      asMap,
    ),
  );
  return state.value;
}