Асин c редукционное действие для извлечения данных вызывает перезагрузку компонента и реагирует на максимальную глубину при перезагрузке - PullRequest
0 голосов
/ 18 апреля 2020

Я пытаюсь создать компонент, который позволяет обнаруживать изменения в хранилище избыточностей. Как только в хранилище установлен флаг shouldUpdateData, компонент, отвечающий за обновление, должен извлечь данные с помощью asyn c создателя действий. В моем случае либо возникает ошибка «Максимальное количество обновлений достигнуто», либо обновление никогда не происходит.

В зависимости от функции отправки stopFetching () (отключает флаг shouldUpdateData), ошибка или результат изменяются. Если я делаю рассылку внутри создателя действия, то есть бесконечные обновления. Если код используется, как показано ниже, обновление не происходит.

Причина, по которой я использовал ловушку useSelector () из «act-redux », заключается в обнаружении изменений в хранилище для атрибута загрузки.

Заранее спасибо.

Вот создатель действия:

export function updateDataAsync(id) {
    return function (dispatch) {

        // dispatch(fetchDataRequest());

        return fetch(`/api/user/${id}/data`, {
            method: "GET",
            headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
            }
        })
        .then(res => res.json())
        .then(
            (result) => {
                let {projects, notes} = result;
                // New data and dispatch function
                dispatch(fetchDataSuccess({projects, notes}));
            },
            (error) => { dispatch(fetchDataFailure(error)) }
        )
    }
}

Вот редуктор для этого создателя действия:

export function savedData(state = DATA_INITIAL_STATE, action) {

    switch(action.type) {
        case FETCH_STATES.FETCH_DATA_REQUEST:
            return {
                ...state,
                loading: true
            }
        case FETCH_STATES.FETCH_DATA_SUCCESS:
            return {
                loading: false,
                data: action.data,
                error: ''
            }
        case FETCH_STATES.FETCH_DATA_FAILURE:
            return {
                loading: false,
                data: {},
                error: action.error.message
            }
        default:
            return state;
    }
}

Компонент React, который выполняет обновление:

function StoreUpdater({ update, userId, shouldUpdate, startFetch, stopFetch, children }) {

    const loading = useSelector(state => state.savedData.loading);
    let reqSent = useRef(false);

    useEffect(()=>{
        if(!reqSent && shouldUpdate) {
            startFetch();
            update(userId)
            reqSent.context = true;
        }
    })

    return loading ? <LoadingAnimation /> : children;
}

const mapStateToProps = (state) => {
    return {
        userId: state.user.id,
        shouldUpdate: state.shouldUpdateData      // The flag that should trigger the update
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        stopFetch: () => { dispatch(setShouldFetchData(false)) },
        update: (id) => { dispatch(updateDataAsync(id)) },
        startFetch: () => dispatch(fetchDataRequest()),
    }
}

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

Ответы [ 3 ]

1 голос
/ 18 апреля 2020

mapStateToProps и mapDispatchToProps были react-redux функциями высшего порядка для connect классов компонентов в хранилище. там равные у функциональных компонентов useSelector и useDispatch. переписать вашу HO C избыточную адаптацию в хуки и добавить [зависимость] при useEffect использовании


function StoreUpdater({ update, userId, shouldUpdate, startFetch, stopFetch, children }) {

 const loading = useSelector(state => state.savedData.loading);
 const userId = useSelector(state => state.user.id);
 const shouldUpdate = useSelector(state => state.shouldUpdateData);
 let reqSent = useRef(false);
 const dispatch = useDispatch() // import from 'react-redux'

 useEffect(()=>{
    if(!reqSent && shouldUpdate) {
        dispatch(startFetch());
        dispatch(update(userId));
        reqSent.context = true;
    }
 }, [reqSent, shouldUpdate, startFetch, dispatch, update, userId]) 

 return loading ? <LoadingAnimation /> : children;
}

export default StoreUpdater ;
0 голосов
/ 18 апреля 2020

Ссылка, которую я создал внутри компонента, ответственного за обновления, вызывала проблему. Ссылка препятствовала отправке обновления из-за ложного утверждения if.

0 голосов
/ 18 апреля 2020

Вы не передаете любую зависимость в useEffect, поэтому она будет вызываться при каждом render, который вызывает бесконечные рендеры

, при изменении useEffect на

    useEffect(()=>{
    if(!reqSent && shouldUpdate) {
        startFetch();
        update(userId)
        reqSent.context = true;
    }
},[])

Для получения полной информации относительно useEffect см. эту ссылку

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...