react-redux бесконечный цикл при запросе данных

Рейтинг: 0Ответов: 1Опубликовано: 12.04.2023

Есть компонент

 export default function DataTable() {
    
      const dispatch = useDispatch()
    
      return (
        <div style={{ height: 400, width: "100%", display: "flex", alignItems: "center", justifyContent: "center" }}>
          <button 
              className="btn--download"
              onClick={() => dispatch({ type: FETCH_DEBTORS })}
            >
              Загрузить данные
            </button>
        </div>
      );
}

В нем я при нажатии на кнопку хочу получать данные. Но при нажатии получаю бесконечное кол-во запросов на сервер.

Так у меня прописана сага с запросом:

const fetchDebtorsListFromApi = () => {
    return fetch('https://642fe3bec26d69edc885f1d9.mockapi.io/debtorslist')
}

function* fetchDebtorsListWorker() {
    const data = yield call(fetchDebtorsListFromApi)
    const json = yield call(() => new Promise(res => res(data.json)))
    yield put(fetchDebtorsAction(json))  
}

export function* debtorsListWatcher() {
    yield takeEvery(FETCH_DEBTORS, fetchDebtorsListWorker)
}

Опытным путем комментирования строк, понял, что бесконечный цикл вызывает строчка "yield put(fetchDebtorsAction(json))". Но что с этим делать - не знаю. GPT тоже не помог за 2 часа общения

Вот так у меня построен reducer:

const defaultState = {
    debtors: []
}

export const FETCH_DEBTORS = 'FETCH_DEBTORS'

export const debtorsReducer = (state = defaultState, action) => {
    switch (action.type) {
        case FETCH_DEBTORS:
            return {...state, debtors: action.payload}
        default:
            return state
    }
}

export const fetchDebtorsAction = () => ({type: FETCH_DEBTORS})

Как мне запрашивать данные 1 раз и класть их в стейт без бесконечных циклов запросов?

Ответы

▲ 0

Фиксится добавлением второго экшена, который будет записывать в стейт отдельно от fetch'a

const defaultState = {
    debtors: []
}

export const FETCH_DEBTORS = 'FETCH_DEBTORS'
export const SET_DEBTORS = 'SET_DEBTORS'

export const debtorsReducer = (state = defaultState, action) => {
    switch (action.type) {
->            case SET_DEBTORS: 
->                return {...state, debtors: action.payload}
        default:
            return state
    }
}
    
->    export const setDebtorsAction = (payload) => ({type: SET_DEBTORS, payload})
    export const fetchDebtorsAction = () => ({type: FETCH_DEBTORS})

И передачу его в метод put() вместо fetchDebtorsAction()

function* fetchDebtorsListWorker() {
    const data = yield call(fetchDebtorsListFromApi)
    const json = yield call(() => new Promise(res => res(data.json())))
->        yield put(setDebtorsAction(json))  
    }