Как вернуть массив из пользовательского хука?

Использую реакт. Получаю с сервера массив и отображаю его как таблицу с пагинацией и сортировкой. Пагинацию и сортировку сделал в виде пользовательских хуков, они работают так как нужно. Но при первом рендере массив возвращаемый из функции сортировки куда-то девается, я так решил потому что таблица пустая, потом когда я меняю сортировку таблица заполняется в соответствии с сортировкой.

App.js:

 const [items, setItems] = useState([]);
 const {setMask, setCurrentColumn, setCurrentCondition, sortedItems} = useSort(items);
 const {setCurrentPage, currentItems, amountOfPages} = usePagination(sortedItems);
 const [isLoaded, setIsLoaded] = useState(false);

мой хук:

export const useSort = (filteredItems) => {

    const [sortedItems, setSortedItems] = useState(filteredItems);
    const [mask, setMask] = useState("");
    const [currentColumn, setCurrentColumn] = useState("Distance");
    const [currentCondition, setCurrentCondition] = useState("greater");

    useEffect(() => {
        SortQuantity(currentCondition, currentColumn);
        SortDistance(currentCondition, currentColumn);
        SortName(currentCondition, currentColumn);

    }, [currentCondition, currentColumn, mask]);

    function SortQuantity (currentCondition, currentColumn) {
        if (currentColumn === "Quantity" && currentCondition === "less") {
            console.log(mask, currentCondition, currentColumn);
            setSortedItems(
                filteredItems.filter(item => item.Quantity < mask)
            )
        } else if (currentColumn === "Quantity" && currentCondition === "greater") {
            console.log(mask, currentCondition, currentColumn);
            setSortedItems(
                filteredItems.filter(item => item.Quantity > mask)
            )
        } else if (currentColumn === "Quantity" && currentCondition === "equal") {
            console.log(mask, currentCondition, currentColumn);
            setSortedItems(
                filteredItems.filter(item => item.Quantity.toString() === mask)
            )
        } else return sortedItems
    }

    function SortDistance (currentCondition, currentColumn) {
        if (currentColumn === "Distance" && currentCondition === "less") {
            console.log(mask, currentCondition, currentColumn);
            setSortedItems(
                filteredItems.filter(item => item.Distance < mask)
            )
        } else if (currentColumn === "Distance" && currentCondition === "greater") {
            console.log(mask, currentCondition, currentColumn);
            setSortedItems(
                filteredItems.filter(item => item.Distance > mask)
            )
        } else if (currentColumn === "Distance" && currentCondition === "equal") {
            console.log(mask, currentCondition, currentColumn);
            setSortedItems(
                filteredItems.filter(item => item.Distance.toString() === mask)
            )
        } else return sortedItems
    }

    function SortName (currentCondition, currentColumn) {
        if (currentColumn === "Name" && currentCondition === "contains") {
            console.log(mask, currentCondition, currentColumn);
            setSortedItems(
                filteredItems.filter(item =>
                    item.Name.toLowerCase().includes(mask.toLowerCase())
                )
            )
        } else return sortedItems
    }

    return {
        setMask,
        setCurrentColumn,
        setCurrentCondition,
        sortedItems
    }
};

Ответы (2 шт):

Автор решения: Sergei Kirjanov
  • фильтрованые строки не стейт, а мемо
  • эффект не нужен
  • функции, вызываемые из use*: или за пределы компонента, или в вызывающий use* или в useCallback
  • useFilter можно сделать короче и использовать несколько раз
const useFilter = (items, column, filterOperation, filterValue) => {
    const filteredItems = useMemo(()=>{
        const check = 
        ....
        return items.filter(check)
    },[items, column, filterOperation, filterValue])
    return filteredItems
}
→ Ссылка
Автор решения: d2207

Я решил проблему с первым рендером, теперь всё нормально. Я добавил setSortedItems в фетч - запрос. Как бы оно теперь работает нормально но я понимаю что это костыль и хотелось бы понять почему useEffect не реагировал на массив зависимостей так как я ожидал. Да я понял что надо использовать useMemo, и я использовал, но с ним такая же ситуация.

async function FetchData() {
            try {
                const response = await fetch('http://localhost:4000/items');
                const json = await response.json();
                setItems(json);
                setIsLoaded(true);
                setSortedItems(json);
                console.log(json);
            } catch (e) {
                console.log(e)
            }
        };
→ Ссылка