Set active for pagination in React-bootstrap

Viewed 107

I tried setting it active, comparing variables return true, and yet, it doesn't set active. What gives?

let pagesArr = [...Array(last_page).keys()].map((item, i)=> {
            
            return <Pagination.Item key={i} active={current_page===(i+1)} page={i+1} onClick={this.props.setPageNumber}>
                {i+1}
            </Pagination.Item>;
        });

which in turn goes in

<Pagination>{pagesArr}</Pagination>

I am using react-redux and even though dispatching goes correctly with correct values, it doesn't set active. It just ignores it...

export const setPageNumber = (e, i) => dispatch => {
    
    let page = e.currentTarget.getAttribute("page");
    console.log("page: ", page);

    let pagination = store.getState().customReports.pagination;

    let first = pagination.from;
    let last = pagination.last_page;

    let next = (Number(page)+1)<=last ? Number(page)+1 : first;
    let prev = (Number(page)-1)<first ? last : (Number(page)-1);

    let index1 = pagination.next_page_url.indexOf("=");

    let next_page_url = pagination.next_page_url.substr(0, index1+1)+next;
    let prev_page_url = pagination.next_page_url.substr(0, index1+1)+prev;
    console.log("pagination: ", pagination);

    dispatch({
        type: PAGINATION,
        payload: {
            current_page: page ? Number(page) : pagination.current_page,
            first_page_url: pagination.first_page_url,
            from: pagination.from,
            last_page: pagination.last_page,
            last_page_url: pagination.last_page_url,
            next_page_url: next_page_url ? next_page_url : pagination.next_page_url,
            path: pagination.path,
            per_page: pagination.per_page,
            prev_page_url: prev_page_url ? prev_page_url : pagination.prev_page_url,
            to: pagination.to,
            total: pagination.total,
            index: i
        }

    });

}

Here is image of it: image

PS: Backend is mine and functioning.

Edit1: This is from docs

Edit2: If i setup logic for setting active state in component itself, instead in redux, then it works. Wth?

Edit3:

Forgot to add reducer...

import { TIME_IN, TIME_OUT, HREF, PAGINATION } from "../actions/types";

const initialState = {
    time_in: new Date(),
    time_out: new Date(),
    href: null,
    pagination: {
        current_page: null,
        first_page_url: null,
        from: null,
        last_page: null,
        last_page_url: null,
        next_page_url: null,
        path: null,
        per_page: null,
        prev_page_url: null,
        to: null,
        total: null,
        index: 0
    }
};

let myState = null;
let time_in = null;
let time_out = null;
let href = null;
let pagination = {
    current_page: null,
    first_page_url: null,
    from: null,
    last_page: null,
    last_page_url: null,
    next_page_url: null,
    path: null,
    per_page: null,
    prev_page_url: null,
    to: null,
    total: null,
    index: 0
};

export default function(state = initialState, action){

    switch(action.type){

        case TIME_IN:
            
            time_in = action.payload;

            myState = {
                time_in: time_in
            };
            
            return myState;

        case TIME_OUT:
        
            time_out = action.payload;

            myState = {
                time_out: time_out
            };
            
            return myState;

        case HREF:
            
            href = action.payload;

            myState = {
                href: href,
                time_in: initialState.time_in,
                time_out: initialState.time_out
            };
            
            return myState;

        case PAGINATION:
            
            pagination.current_page = action && action.payload && action.payload.current_page ? action.payload.current_page : initialState.current_page;
            pagination.first_page_url = action && action.payload && action.payload.first_page_url ? action.payload.first_page_url : initialState.first_page_url;
            pagination.from = action && action.payload && action.payload.from ? action.payload.from : initialState.from;
            pagination.last_page = action && action.payload && action.payload.last_page ? action.payload.last_page : initialState.last_page;
            pagination.last_page_url = action && action.payload && action.payload.last_page_url ? action.payload.last_page_url : initialState.last_page_url;
            pagination.next_page_url = action && action.payload && action.payload.next_page_url ? action.payload.next_page_url : initialState.next_page_url;
            pagination.path = action && action.payload && action.payload.path ? action.payload.path : initialState.path;
            pagination.per_page = action && action.payload && action.payload.per_page ? action.payload.per_page : initialState.per_page;
            pagination.prev_page_url = action && action.payload && action.payload.prev_page_url ? action.payload.prev_page_url : initialState.prev_page_url;
            pagination.to = action && action.payload && action.payload.to ? action.payload.to : initialState.to;
            pagination.total = action && action.payload && action.payload.total ? action.payload.total : initialState.total;
            pagination.index = action.payload.index;
            console.log("paginacija: ", pagination);
            myState = {
                pagination: pagination,
                time_in: initialState.time_in,
                time_out: initialState.time_out
            };
            
            return myState;

        default:
            return state;

    }
    
} 
2 Answers

Changes in react redux state won't trigger re-rendering for components. You should track your component state using useState().

I kind figured it out after experimenting with various paginators. Since none of them are suitable for my purpose, i took general advices and this and that's from all of them. Basically how to solve my specific problem.

Here it is:

Structure that i get from BE(Laravel). Mind you, when is sent, there is data in it. See the image of the before.


    {
        current_page: null,
        first_page_url: null,
        from: null,
        last_page: null,
        last_page_url: null,
        next_page_url: null,
        path: null,
        per_page: null,
        prev_page_url: null,
        to: null,
        total: null,
        index: 0
    };

And method for getting first page:

    firstPage(){
            this.setState({
                pageIndex: 0
            }, ()=>{
                this.props.get_vehicles_custom({page: this.state.pageIndex+1});
    
            });
        }

An method for getting last page:


    lastPage(){
            this.setState({
                pageIndex: this.props.pagination.last_page-1
            }, ()=>{
                this.props.get_vehicles_custom({page: this.state.pageIndex+1});
    
            });
        }

And method for getting previous page, mind you, if user goes beyond first page, pages start from last.


    prevPage(){
    
            let pagination = this.props && this.props.pagination ? this.props.pagination : null;
            let first = 0;
            let last = pagination.last_page;
    
            this.setState({
                pageIndex: this.state.pageIndex-1 >= first ? this.state.pageIndex-1 : last-1
            }, ()=>{
                this.props.get_vehicles_custom({page: this.state.pageIndex+1});
    
            });
    
        }

An next page method:


    nextPage(pagination){
    
            let first = 0;
            let last = pagination.last_page;
    
            this.setState({
                pageIndex: this.state.pageIndex+1 < last ? this.state.pageIndex+1 : first
            }, ()=>{
                this.props.get_vehicles_custom({page: this.state.pageIndex+1});
    
            });
    
        }

Method for customizing items per page:


    handleSubmitPerPage(event){
    
            event.preventDefault();
            let forma = event.target; 
            let elements = forma.elements;
            let per_page = elements[0].value;
            let metoda = elements[1].checked ? elements[1].value : (elements[2].checked ? elements[2].value : null);
            let per_page_id = 1;
            if(per_page && metoda && per_page_id){
                let data = {
                    per_page: per_page,
                    metoda: metoda,
                    "per_page_id": per_page_id
                }
                this.props.set_per_page(data);
                this.props.get_vehicles_custom({page: 1});
    
            }
            this.firstPage();
    
        }

Method when you click individual buttons:


    setActive(e, i){
    
            this.props.setPageNumber(e, i);
            let pagination = this.props && this.props.pagination ? this.props.pagination : null;
            let page = e.currentTarget.getAttribute("page");
            if(pagination.last_page>1){
                this.setState({
                    pageIndex: page-1
                }, () => {
                    this.props.get_vehicles_custom({page: this.state.pageIndex});
    
                });
            }
    
        }

And method to use with an ellipsis:


    const setVisiblePages = (paginacija) =>{
                
                let pageIndex = null;
                let last_page = null;
                let siblings = 1;
                
                pageIndex = this.state.pageIndex;
                last_page = paginacija && paginacija.last_page && paginacija.last_page ? paginacija.last_page : null;
                
                let myPages = [];
                
                if(pageIndex===0 && pageIndex<=last_page && pageIndex+siblings<=last_page && pageIndex+(siblings*2)<=last_page){
                    
                    myPages = [
                        <Pagination.Item key={pageIndex} active={pageIndex===this.state.pageIndex} page={pageIndex+1} onClick={(e)=>{this.setActive(e, pageIndex)}}>
                            {pageIndex+1}
                        </Pagination.Item>,
            
                        <Pagination.Item key={pageIndex+siblings} page={pageIndex+1+siblings} onClick={(e)=>{this.setActive(e, pageIndex+siblings)}}>
                            {pageIndex+1+siblings}
                        </Pagination.Item>,
            
                        <Pagination.Item key={pageIndex+(2*siblings)} page={pageIndex+1+(2*siblings)} onClick={(e)=>{this.setActive(e, pageIndex+(siblings*2))}}>
                            {pageIndex+1+(2*siblings)}
                        </Pagination.Item>,
        
                        <Pagination.Ellipsis key={"elip"+(pageIndex+3)}/>].filter(Boolean);
        
                }
                
                if(pageIndex>=0 && pageIndex<=last_page && pageIndex-siblings>=0 && pageIndex+siblings<=last_page){

                    let ellipsis1 = pageIndex-siblings> 0 ? <Pagination.Ellipsis key={"elip"+(pageIndex+3)}/> : null;
                    let ellipsis2 = (pageIndex+siblings)<last_page-1 ? <Pagination.Ellipsis key={"elip"+(pageIndex+4)}/> : null;
                    myPages = [
        
                        ellipsis1,
        
                        <Pagination.Item key={pageIndex-siblings} page={pageIndex+1-siblings} onClick={(e)=>{this.setActive(e, pageIndex-siblings)}}>
                            {pageIndex+1-siblings}
                        </Pagination.Item>,
            
                        <Pagination.Item key={pageIndex} active={pageIndex===this.state.pageIndex} page={pageIndex+1} onClick={(e)=>{this.setActive(e, pageIndex)}}>
                            {pageIndex+1}
                        </Pagination.Item>,
            
                        <Pagination.Item key={pageIndex+siblings} page={pageIndex+1+siblings} onClick={(e)=>{this.setActive(e, pageIndex+siblings)}}>
                            {pageIndex+1+siblings}
                        </Pagination.Item>,
        
                        ellipsis2].filter(Boolean);
        
                }
                
                if(pageIndex+1==last_page && pageIndex-(2*siblings)>=0){

                    myPages = [
                        <Pagination.Ellipsis key={"elip"+(pageIndex+3)}/>,
        
                        <Pagination.Item key={pageIndex-(2*siblings)} page={pageIndex+1-(2*siblings)} onClick={(e)=>{this.setActive(e, pageIndex-(siblings*2))}}>
                            {pageIndex+1-(2*siblings)}
                        </Pagination.Item>,
            
                        <Pagination.Item key={pageIndex-siblings} page={pageIndex+1-siblings} onClick={(e)=>{this.setActive(e, pageIndex)}}>
                            {pageIndex+1-siblings}
                        </Pagination.Item>,
            
                        <Pagination.Item key={pageIndex} active={pageIndex===this.state.pageIndex} page={pageIndex+1} onClick={(e)=>{this.setActive(e, pageIndex-siblings)}}>
                            {pageIndex+1}
                        </Pagination.Item>].filter(Boolean);
        
                }
        
                if(pageIndex>=0 && pageIndex<=last_page && last_page<=3){
                    console.log("mojTest4");
                    let pages = [];
                    for(let i=0;i<last_page;i++){
    
                        pages.push(
                            <Pagination.Item key={i} active={i===pageIndex} page={i+1} onClick={(e)=>{this.setActive(e, i)}}>
                                {i+1}
                            </Pagination.Item>
                        );
                        
                    }
                    myPages = [...pages].filter(Boolean)
        
                }
        
                if(this.state.setVisiblePages>3){
        
                    myPages = [...this.state.setVisiblePages, <Pagination.Ellipsis key={"elipsa"}/>].filter(Boolean);
        
                }
                
                return myPages;
    
            };

I know, it isn't by current standards, hooks and all, but i didn't know about them at the time.

Since all logic is good and working,I'm gonna finish it up by moving to redux and i'm planning to move React part to functional components which is gonna be quite ordeal considering number of components i have and i'm in no way FE person. At least functionalities are all there...

Thanks everybody for help.

Related