Каков наилучший способ использовать избыточное действие в useEffect? - PullRequest
1 голос
/ 04 марта 2020

У меня есть компонент React, как показано ниже (некоторые части опущены), и использующий избыточность для управления состоянием. Действие getRecentSheets содержит запрос ajax и отправляет ответ на сокращение, которое обновляет state.sheets.recentSheets данными ответа.

Все это работает, как и ожидалось, но при построении выдает предупреждение о У useEffect отсутствует зависимость: 'getRecentSheets' . Но если я добавлю getRecentSheets к массиву зависимостей Effect, он начнет бесконечно перезапускаться и тем самым заморозит приложение.

Я прочитал React do c о перехватчике useEffect https://reactjs.org/docs/hooks-faq.html#is -it-safe-to-опустить-функции-из-списка-зависимостей но это не хороший пример для такого варианта использования. Я предполагаю, что это что-то с useCallback или response-redux useDispatch, но без примеров я не уверен, как это реализовать.

Подскажите, пожалуйста, какой самый краткий и идиоматичный c способ использовать действие приставки в useEffect и избежать предупреждений об отсутствующих зависимостях?

import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import SheetList from '../components/sheets/SheetList';
import { getRecentSheets } from '../store/actions/sheetsActions';

const mapStateToProps = (state) => {
    return {
        recentSheets: state.sheets.recentSheets,
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        getRecentSheets: () => dispatch(getRecentSheets()),
    }
}

const Home = (props) => {
    const {recentSheets, getRecentSheets} = props;

    useEffect(() => {
        getRecentSheets();
    }, [])

    return <SheetList sheets={ recentSheets } />
};

export default connect(mapStateToProps, mapDispatchToProps) (Home);

Ответы [ 3 ]

1 голос
/ 05 марта 2020

Передача пустого массива в ваш хук говорит React, что ваша хук-функция не будет иметь никаких зависимых значений ни от props, ни от состояния.

useEffect(() => {
   getRecentSheets();
}, [])

Бесконечное l oop возникает, когда вы объявляете диспетчер как зависимость от крючка. Когда компонент инициализирован, props.recentSheets не был установлен и будет перезапущен, как только вы сделаете ваш AJAX вызов.

useEffect(() => {
   getRecentSheets();
}, [getRecentSheets])

Вы можете попробовать что-то вроде этого:

const Home = ({recentSheets}) => {
    const getRecentSheetsCallback = useCallback(() => {
       getRecentSheets();
    })

    useEffect(() => {
        getRecentSheetsCallback();
    }, [recentSheets]) // We only run this effect again if recentSheets changes


    return <SheetList sheets={ recentSheets } />
};

Независимо от того, сколько раз Homes выполняет повторную визуализацию, вы сохраняете запомненную функцию для своего вызова диспетчеризации.

В качестве альтернативы, вы можете столкнуться с тем, что можете найти похожие шаблоны, использующие локальное состояние, и затем сделать свой эффект "зависимым" от sheets.

const [sheets, setSheets] = useState(recentSheets)

Надеюсь, это поможет

0 голосов
/ 05 марта 2020

В конце концов, похоже, что правильный путь будет следующим:

// ...
import { useDispatch } from 'react-redux';
import { getRecentSheets } from '../store/actions/sheetsActions';

const Home = props => {
    const dispatch = useDispatch();

    useEffect(() => {
        dispatch(getRecentSheets());
    }, [dispatch])

    // ...
};

Таким образом, он не будет жаловаться на отсутствие getRecentSheets в массиве зависимостей. Как я понял из чтения React, сделайте c на хуках, потому что это не определено внутри компонента. Хотя я новичок в веб-интерфейсе и надеюсь, что ничего не испортил здесь.

0 голосов
/ 04 марта 2020

Я бы добавил проверку, чтобы узнать, существует ли recentSheets или нет, используя это как мою зависимость.

useEffect(() => {
    if (!recentSheets) getRecentSheets();
}, [recentSheets])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...