跨同一组件的不同实例的独立传奇呼叫/响应?

时间:2019-03-12 11:30:18

标签: reactjs react-redux redux-saga

我对反应,还原和sagas有点陌生,但是我掌握了很多东西。

我有一个组件(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分发中获取数据时,{{1}的所有实例 }组件使用返回的数据进行更新。它们全部显示相同的数据。

在我生命中,我无法弄清楚如何仅监听组件本身的特定实例。我以为那应该是sagas的工作方式?

感谢您的帮助!

编辑/答案:

Reducer函数是漂亮的教科书,看起来像:

Results.jsx

1 个答案:

答案 0 :(得分:2)

Sagas只是一种中间件,可以减轻异步任务的负担并在View层之外存储写操作。最终,组件上的道具取决于您存储的方式。特别是在这种情况下,如果prop1prop2是从商店中的同一位置拾取的,则在所有Results实例中都将具有相同的值。

如果不同的实例需要不同的数据,请根据映射到该实例的一些唯一ID将其分段。减速器看起来像:

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>;
}