Независимый сага-вызов / ответы для разных экземпляров одного и того же компонента? - PullRequest
0 голосов
/ 12 марта 2019

Я немного новичок в реагировании, редуксе и саге, но я разбираюсь в вещах.

У меня есть компонент (Results.jsx), который отображает результаты определенного реальногомировое событие через сагу, вызывающее внешний API:

componentDidMount() {
    if (this.props.thing_id) {
        this.props.getResults(this.props.thing_id);
    }
}

...

const mapStateToProps = (state) => {
    return {
        prop1: state.apiReducer.thing_results.data1,
        prop2: state.apiReducer.thing_results.data2,
        fetching: state.apiReducer.fetching,
        error: state.apiReducer.error,
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        getResults: (thing_id) => dispatch({type: "RESULTS_DATA_REFRESH", payload: thing_id})
    };
};

Все это прекрасно работает.Пока ... Ну, я использую интерфейс с вкладками, который позволяет мне динамически добавлять кучу дополнительных экземпляров Results.jsx, чтобы я мог видеть кучу разных наборов результатов на одном экране.

проблема заключается в том, что, когда новый экземпляр компонента Results.jsx загружается и получает данные от RESULTS_DATA_REFRESH отправки, все экземпляров компонента Results.jsx обновляются с данными, которые возвращаются.Они все показывают одни и те же данные.

Насколько я понимаю, я не могу понять, как получить конкретный экземпляр компонента только для прослушивания результатовс чего он сам отправлен.Я думал, что именно так должны работать саги?

Любая помощь приветствуется!

Правки / Ответы:

Функция редуктора довольно удобна,выглядит так:

const initialState = {
    fetching: false,
    error: null,
    thing_results: {
        data1: null,
        data2: null,
    },
};

export default (state = initialState, action) => {
    switch (action.type) {

        //...

        case "RESULTS_DATA_REFRESH":
            return {...state, fetching: true};
        case "RESULTS_DATA_SUCCESS":
            return {...state, fetching: false, thing_results: action.results.data, error: null};
        case "RESULTS_DATA_FAILURE":
            return {...state, fetching: false, thing_results: null, error: action.error};

        default:
            return state;
    }
};

1 Ответ

2 голосов
/ 12 марта 2019

Sagas - это не что иное, как промежуточное ПО для разгрузки асинхронных задач и хранения записей из слоя View.В конечном счете, опора для вашего компонента зависит от того, как вы его храните.В частности, в этом случае, если prop1 и prop2 будут получены из одного и того же места в магазине, оно будет иметь одинаковое значение во всех случаях Results.

Если вам требуются разные данныедля разных экземпляров разделите его на основе уникального идентификатора, сопоставленного с экземпляром.Ваш редуктор будет выглядеть так:

const apiReducer = (state = {}, action) => {
  switch (action.type) {
    case "RESULTS_DATA_REFRESH":
      return {
        ...state,
        [action.payload]: { data: null, fetching: true }
      };
    case "RESULTS_DATA_SUCCESS":
      return {
        ...state,
        /** You should be getting back the id from the api response.
         * Else append the id in the success action from your api saga.
         */
        [action.payload.id]: { data: action.results.data, fetching: false }
      };
    case "RESULTS_DATA_FAILURE":
      return {
        ...state,
        [action.payload.id]: {
          data: null,
          fetching: false,
          error: action.error
        }
      };
    default:
      return state;
  }
};

/** Other reducers */
const otherReducerA = function() {};
const otherReducerB = function() {};

export default combineReducers({ apiReducer, otherReducerA, otherReducerB });

И доступ к нему будет выглядеть так:

const mapStateToProps = state => {
  return {
    data: state.apiReducer
  };
};

function Results({ data, thing_id }) {
  return <div>{data[thing_id].data}</div>;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...