React - 通过action + reducer进行分页以从api获取新数据

时间:2018-06-07 12:09:36

标签: reactjs redux react-redux

我有网格视图,我有一些记录。我想要的是,当我点击网格视图的另一个页面时,pageChange方法被触发,这就是重点。我可以直接更改道具,从我的api获取我的页面的新数据,一切正常,我的页面被更改,新数据被加载,但是据我所知,道具是不可变的所以我应该这样做,我应该通过reducer设置状态以获取数据。

相反,我创建了setPaging操作,其中显示了"store"pageChange调用的方法,我的页面已成功更改,但我不知道如何从我的网页获取新数据API,必须处理它的动作永远不会被解雇。

我应该在我的dispatch方法中发送另一个setPaging,但由于它的异步,我不知道它的好方法。

这是我的processList组件,我在其中呈现我的网格视图。

type ProcessListProps =
    ProcessState.IProcessesStateType
    & typeof ProcessState.actionCreators
    & RouteComponentProps<{}>;

class ProcessList extends React.Component<ProcessListProps, {}> {
    constructor(props) {
        super(props);
    }   
    componentWillMount() {
        this.getData();
    }
    setPaging = (skip: number, take: number) => {
        this.props.setPaging(take, skip);
    };
    // send request to post api to get data
    getData = () => {
        this.props.requestProcesses(this.props.filter);
    };

    filterData = (event) => {
        this.getData();
    }

    pageChange = (event) => {
        this.props.filter.query.take = event.page.take;
        this.props.filter.query.skip = event.page.skip;
        this.getData();
        //this.setPaging(event.page.skip, event.page.take);
    };
    // handling filter input change
    inputFilterChangeHandler = (event) => {
        const type = event.target.props.type;
        const value = event.value;
        let jsonFilter = this.props.filter.query.filter;

        // check if input has some value
        if (value.length > 0) {
            jsonFilter[type] = value;
        }

        // no value in input => remove property from json filter object
        else {
            this.removeByKey(this.props.filter.query.filter, type)
        }
    };

    // remove json object property by it"s key
    // returns remaining object properties
    removeByKey = (myObj, deleteKey) => {
        return Object.keys(myObj)
            .filter(key => key !== deleteKey)
            .reduce((result, current) => {
                result[current] = myObj[current];
                return result;
            }, {});
    }

    render() {
        return (
            <div className="tab-content-container">
                <div className="separator"></div>
                <div className="col-xs-12 col-md-12 example-col">
                    <Input label="JobId" id="jobIdFilter" type="JobId" onChange={this.inputFilterChangeHandler} />
                    <Input label="Type" id="typeFilter" type="Type" onChange={this.inputFilterChangeHandler} />
                    <Button type="primary" onClick={this.filterData}>
                        Filter
                    </Button>
                </div>
                <Button type="primary" onClick={this.onReload}>
                    Reload
                </Button>
                <div className="button-group">
                    <span className="ant-divider-vertical" />
                </div>
                <div className="tab-content-container">
                    <Grid data={this.props.data}
                        onPageChange={this.pageChange}
                        total={this.props.totalItemsCount}
                        skip={this.props.filter.query.skip}
                        pageSize={this.props.filter.query.take}
                        filterable={false}
                        pageable={true}
                    >
                        <Column field="action" title="Action"></Column>
                        <Column field="jobId" title="Id"></Column>
                        <Column field="type" title="Type"></Column>
                        <Column field="initTime" title="Init time"></Column>
                        <Column field="finishTime" title="Finish time"></Column>
                        <Column field="author" title="Author"></Column>
                    </Grid>
                </div>
            </div>
        );
    };
};

export default connect(
    (state: ApplicationState) => state.processes,
    ProcessState.actionCreators
)(ProcessList) as typeof ProcessList;

这是store组件,其中actionCreator具有已定义的函数,reducer我为了简洁而删除了大量代码

export interface IFilterGrid {
    pageable: boolean,
    query: {
        collectionName: string,
        filter: {},
        sort: {},
        projection: {},
        take: number,
        skip: number,
        includeTotalCount: boolean,
        context: any,
    }
}

export interface IProcessesStateType {
    totalItemsCount: number;
    filter: IFilterGrid;
    data: ServiceApi.ProcessDocument[];
}

interface ServiceApiProcessGetAllType {
    type: typeof SERVICE_API_PROCESS_GETALL;
    payload: { query: any };
};

interface ServiceApiProcessGetAllSuccessType {
    type: typeof SERVICE_API_PROCESS_GETALL_SUCCESS;
    processList: ServiceApi.ProcessDocument[];
    totalItemsCount: number;
};

interface ISetPaging {
    type: typeof SET_PAGING_OPTIONS,
    pageSize: number;
    skip: number;
};

export const setPagingAction = (take: number, skip: number): ISetPaging => ({
    type: SET_PAGING_OPTIONS,
    pageSize: take,
    skip: skip
});

export const serviceApiProcessGetAll = (filter: any): ServiceApiProcessGetAllType => ({
    type: SERVICE_API_PROCESS_GETALL,
    payload: { query: filter },
});

export const serviceApiProcessGetAllSuccess = (data: ServiceApi.QueryResultOfProcessDocument): ServiceApiProcessGetAllSuccessType => ({
    type: SERVICE_API_PROCESS_GETALL_SUCCESS,
    processList: data.data,
    totalItemsCount: data.totalCount
});

type KnownAction =
    ServiceApiProcessGetAllType |
    ServiceApiProcessGetAllSuccessType | 
    ServiceApiProcessGetAllFailure |
    ISetPaging

export const actionCreators = {
    requestProcesses: (filter: any): AppThunkAction<KnownAction> => (dispatch, getState) => {
        client.apiProcessDataPost(filter.query)
            .then(result => dispatch(serviceApiProcessGetAllSuccess(result)))
            .catch(error => dispatch(serviceApiProcessGetAllFailure(error)));
        dispatch(serviceApiProcessGetAll(filter.query));
    },

    //method for setting up paging on grid
    setPaging: (take: number, skip: number): AppThunkAction<KnownAction> => (dispatch, getState) => {
        dispatch(setPagingAction(take, skip));
    },
};

const unloadedState: IProcessesStateType = {
    data: [],
    filter: {
        pageable: true,
        query: {
            collectionName: "",
            filter: {},
            sort: {},
            projection: {},
            take: 5,
            skip: 0,
            includeTotalCount: true,
            context: null,
        }
    },
    totalItemsCount: 0,
};

export const reducer: Reducer<IProcessesStateType> = (state: IProcessesStateType, incomingAction: Action) => {
    const action = incomingAction as KnownAction;
    switch (action.type) {
        case SERVICE_API_PROCESS_GETALL:
            return {
                ...state
            };

        case SERVICE_API_PROCESS_GETALL_SUCCESS:
            return {
                ...state,
                data: action.processList,
                totalItemsCount: action.totalItemsCount
            };

        case SERVICE_API_PROCESS_GETALL_FAILURE:
            return {
                ...state,
            };

        case SET_PAGING_OPTIONS:
            return Object.assign({},
                state,
                {
                    filter: {
                        query: {
                            take: action.pageSize,
                            skip: action.skip
                        }
                    }
                });

    default:
        // The following line guarantees that every action in the KnownAction union has been covered by a case above
        const exhaustiveCheck: never = action;
    }
    return state || unloadedState;
};

0 个答案:

没有答案