Redux重击–正确实施

时间:2019-04-02 21:31:04

标签: reactjs redux redux-thunk

我对redux thunk的实现导致覆盖数组数据。

显然流程中有问题,但我无法弄清楚。

基本上,我有两个组件 StringInstrument UsersListedItems

StringInstrument 将(通过axios)从数据库中获取数据以获取项目所有者的列表。

将为每个所有者创建一个 UsersListedItems 组件,该组件还将通过所有者ID从数据库(图像)中获取数据。

所以我想说 StringInstrument 实际上是创建 UsersListedItems

以下是 StringInstrument 的一些代码:

if (this.props.error) {
        return <p>Sorry! There was an error loading the items</p>;
    }
    if (this.props.isLoading) {
        return <CircularProgress/>;
    }

     return (
        <div>
            <Grid container spacing={24}>
                {this.props.itemOwner.map((item, index) => (
                    <Grid item xs={6} sm={3} key={index}>
                        <UsersListedItems
                            ownerId={item.ownerId}
                            userName={item.userName}
                            categoryId={1}>
                        </UsersListedItems>
                    </Grid >)
                )}
            </Grid>
        </div>
    );
   }
  }

const mapStateToProps = (state) => {
return {
    itemOwner: state.itemOwner.data,
    isLoading: state.itemOwner.isLoading,
    error: state.itemOwner.error
}
 }

const mapDispatchToProps = (dispatch) => {
return {
    getItemOwners: (id) => dispatch(itemAction.getItemOwners(id))
  }

这就是我实施动作和减速器的方式。

export function getItemOwner(state = initState, action) {
switch (action.type) {
    case GET_ITEM_OWNER_START:
        state = Object.assign({}, state, { isLoading: true });
        break;
    case GET_ITEM_OWNER_SUCCESS:
        state = Object.assign({}, state, { data: action.payload, isLoading: false });
        break;
    case GET_ITEM_OWNER_ERROR:
        state = Object.assign({}, state, { error: action.payload, isLoading: false });
        break;
}
return state;
 }

 export function getItems(state = initState, action) {
switch (action.type) {
    case GET_ITEMS_START:
        state = Object.assign({}, state, { isLoading: true });
        break;
    case GET_ITEMS_SUCCESS:
        state = Object.assign({}, state, { data: action.payload, isLoading: false });
        break;
    case GET_ITEMS_ERROR:
        state = Object.assign({}, state, { error: action.payload, isLoading: false });
        break;
}
return state;


export const getItemOwners = (categoryId) => {
return (dispatch, getState) => {
    //make async call to database
    dispatch({ type: GET_ITEM_OWNER_START });
    axios.get('api/items/owner/category/' + categoryId)
        .then(function (response) {
            dispatch({ type: GET_ITEM_OWNER_SUCCESS, payload: response.data });
        })
        .catch(function (error) {
            dispatch({ type: GET_ITEM_OWNER_ERROR, payload: error });
        });
}
 };

  export const getItems = (categoryId, ownerId) => {
   return (dispatch, getState) => {
    dispatch({ type: GET_ITEMS_START });
    axios.get('api/items/' + categoryId + '/' + ownerId)
        .then(function (response) {
            dispatch({ type: GET_ITEMS_SUCCESS, payload: response.data });
        })
        .catch(function (error) {
            dispatch({ type: GET_ITEMS_ERROR, payload: error });
        });
}

我不确定如何按顺序管理\控制调度程序的流程,以便它适合组件结构而不覆盖所收集的数据。

如您在附件图像中看到的,在末尾有4个“ GET_ITEM_SUCCESS”,其中每个将覆盖下一个。

enter image description here

希望这个长代码示例对我很清楚,并表示歉意。

谢谢

1 个答案:

答案 0 :(得分:0)

我认为您遇到的问题是,您在任何给定时间都只存储一个处于状态的项目,而每个后续调用都会破坏处于状态的内容。如果我对此假设是正确的,那么解决方案将是使用categoryId和ownerId作为将数据存储在对象中的键,该对象的值将是有效负载。

首先,您需要在操作中提供categoryId和ownerId

export const getItems = (categoryId, ownerId) => (dispatch, getState) => {
  dispatch({ type: GET_ITEMS_START, categoryId, ownerId });
  axios.get('api/items/' + categoryId + '/' + ownerId)
    .then(function (response) {
      dispatch({ type: GET_ITEMS_SUCCESS, payload: response.data, categoryId, ownerId });
    })
    .catch(function (error) {
      dispatch({ type: GET_ITEMS_ERROR, payload: error, categoryId, ownerId });
    });

下一步,您需要更新化简器以将有效负载分配给对象

const key = `${action.categoryId}-${action.ownerId}`; // unique key for the payload
switch (action.type) {
    case GET_ITEMS_START:
        state = Object.assign({}, state, { isLoading: true, data: Object.assign({}, state.data, {[key]: []}) });
        break;
    case GET_ITEMS_SUCCESS:
        state = Object.assign({}, state, { data: Object.assign({}, state.data, { [key]: action.payload }), isLoading: false });
        break;
    case GET_ITEMS_ERROR:
        state = Object.assign({}, state, { error: action.payload, isLoading: false });
        break;
}

最后,您需要通过props(redux)将数据映射到组件的状态。然后,您可以使用相同的关键项访问这些项[${categoryId}-${ownerId}