我对反应,还原和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
答案 0 :(得分:2)
Sagas只是一种中间件,可以减轻异步任务的负担并在View层之外存储写操作。最终,组件上的道具取决于您存储的方式。特别是在这种情况下,如果prop1
和prop2
是从商店中的同一位置拾取的,则在所有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>;
}