Реакция условного рендеринга вызывает несколько вызовов API - PullRequest
0 голосов
/ 05 декабря 2018

Я использую React + Redux + Redux-Saga.

В моем сценарии я вызываю 2 apis - для Config и для данных (после получения Config)

У меня проблема при вызове для Data.Короче говоря:

Это работает:

Файл TestRoute.jsx (пока не используется isConfig):

import React from 'react';
import { connect } from 'react-redux';
import TestComponent from '../components/Test';

const Test = ({ isConfig }) => <div>
  <TestComponent />
  <TestComponent />
  <TestComponent />
  <TestComponent />
</div>

const mapStateToProps = state => ({
  isConfig: !!state.config.payload.tenantId
});

export default connect(mapStateToProps)(Test);

TestComponent.jsx

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { dataRequestInit } from '../state/actions/data';

class Test extends Component {
  componentDidMount() {
    this.props.dataRequestInit('https://data/api/url');
  }

  render() {
    return <p>hello</p>;
  }
}

const mapStateToProps = state => ({})

export default connect(
  mapStateToProps,
  { dataRequestInit }
)(Test);

Saga-файл:

const getIsFetching = (state, url) => state.data.isFetching.includes(url);

function* fetchData(url) {
  try {
    const isFetching = yield select(getIsFetching, url);

    if (!isFetching) {
      yield put(actions.fetchDataIsFetching(url));

      const response = yield call(api, url);

      console.log('response', response);
    }
  } catch (err) {
    console.log('handle error', err);
  }
}

export default function* DataSaga() {
  yield takeEvery(actionTypes.FETCH_DATA_INIT, fetchData);
}

В этом случае все удачные вызовы в первый раз устанавливают isFetching и выполняется один запрос API. Представление Redux DevTools

Но если я заново создаю свой файл Route, чтобы начать использовать флаг isConfig и условно отрисовываю TestComponents:

const Test = ({ isConfig }) =>
  isConfig && (
    <div>
      <TestComponent />
      <TestComponent />
      <TestComponent />
      <TestComponent />
    </div>
  );

Все сходит с ума, и 4 вызова APIиду на сервер.Это потому, что сначала запускаются 4x действия DATA / FETCH_INIT, а затем 4x DATA / SET_IS_FETCHING Представление Redux DevTools вместо ожидаемого: 1x DATA / FETCH_INIT 1x DATA / SET_IS_FETCHING 3x DATA / FETCH_INIT, как ранее.

Может кто-нибудь объяснить мне, почему это происходит?Что мне здесь не хватает и, возможно, как решить проблему?

1 Ответ

0 голосов
/ 05 декабря 2018

Я вижу вашу проблему, вы монтируете один и тот же компонент 4 раза, см. Ниже:

componentDidMount() {
  this.props.dataRequestInit('https://data/api/url');
}

И затем вы рендерите это 4 раза:

  <TestComponent />
  <TestComponent />
  <TestComponent />
  <TestComponent />

Это сработаетотдельный экземпляр вызова функции для каждого компонента, имеющий переменную для isFetching, не помешает другим выполнять свои вызовы API.

Еще одна важная вещь, которую нужно отметить, если этот компонент должен быть обработан 4раз, и все они нуждаются в одних и тех же данных, было бы лучше передать управление родительскому компоненту, получить данные один раз и передать их вашему компоненту в каждом случае, например:

<TestComponent data={state.data}/>

Кроме того, ваш случай редуктора для этого действия должен выглядеть примерно так:

switch (action.type) {
  case AUTH_REQUEST:
    return {
      ...state
    }

Переменная состояния с оператором распространения, она сохраняет состояние от предыдущих действий, в вашем случае переменная извлечения.

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

Ллойд

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