Решите проблемы с реакциями / исчерпывающими зависимостями при обновлении redux in useEffect

Можете ли вы помочь мне решить загадки useEffect?

Хочу удовлетворить линтер react-hooks/exhaustive-depsrule, но также имеет компонент, который не перерисовывается все время. Мой компонент должен агрегировать данные, если он загружается впервые. Эти данные извлекаются из redux, затем выполняется суммирование и данные сохраняются обратно в redux.

Как объясняется в этом вопросе, я мог бы переместить агрегацию в компонент, в который добавляются данные, но это вынудило бы меня чаще обновлять массивы после добавления акций или транзакции, и даже я никогда не просматриваю агрегат.

Этот вопрос также указывает на сообщение Дэна Абрамова, чтобы не отключать правило линтера. Это позволило мне прийти к выводу, что просто оставлять что-то в массиве useEffect - это не выход, как в моем примере.

Теперь вопрос, как это решить?

import React, { useEffect } from "react";
import { useDispatch } from "react-redux";

import { ITransactionArray } from "../../../store/account/types";
import { IStockArray, STOCKS_PUT } from "../../../store/portfolio/types";
import { useTypedSelector } from "../../../store/rootReducer";
import { AppDispatch } from "../../../store/store";

const aggregateStockQuantities = (
    stocks: IStockArray,
    transactions: ITransactionArray
): IStockArray => {
    console.log("run Value/aggregateStockQuantities");

    const newStocks = [...stocks];
    newStocks.forEach((s) => {
        s.quantity = 0;
        return s;
    });

    transactions.forEach((t) => {
        newStocks.forEach((s) => {
            if (s.quantity !== undefined && t.isin === s.isin) {
                s.quantity += t.quantity;
            }

            return s;
        });
    });

    return newStocks;
};

const Test: React.FC = () => {
    const dispatch: AppDispatch = useDispatch();
    const { stocks } = useTypedSelector((state) => state.portfolio);
    const { transactions } = useTypedSelector((state) => state.account);
    const stockQuantities = aggregateStockQuantities(stocks, transactions);

    useEffect(() => {
        dispatch({
            type: STOCKS_PUT,
            payload: stockQuantities,
        });
    }, [dispatch]);
    // only works if I leave out stockQuantities
    // but then warning:  React Hook useEffect has a missing dependency: 'stockQuantities'. Either include it or remove the dependency array  react-hooks/exhaustive-deps


    // Render
}

Обновление №1: пришлось изменить aggregateStockQuantities поэтому количество вначале равно нулю.

1 ответ

Я бы посоветовал сделать селектор, который выбирает только aggregateStockQuantities из состояния редукции.

И переместите const stockQuantities = aggregateStockQuantities(stocks, transactions); внутри useEffect крючок.

Другие вопросы по тегам