Problem with search function in combination with pagination (React, Redux-Toolkit)

Viewed 81

I'm having a problem with a search functionality in combination with pagination. Whenever I perform a search query on an array of objects, a filter method in the reducer selects the objects that match the condition set in the includes method. All is fine. However if I navigate to the next page in a filtered list( if a search query returns 2 pages or more) and perform a new search query I get no results, a blank page. In my Dev-Tools I can see that my state updates the way I want it, but the UI shows a blank page. Again, this happens only after navigating to a next page within an already filtered list.
Somehow I need to populate the filtered list after every search query with the entire list of objects.
App build in react and redux-toolkit.
Search options with react-select dropdown menu.

State after search query:

enter image description here

Reducer:

 const initialState = {
    realestate: [],
    isSuccess: false,
    isLoading: false,
    filtered: [],
    message: '',
    }

export const estateSlice = createSlice({
    name: 'realestate',    // Reducer name
    initialState,
    reducers: {
        reset: () => initialState,
         filteredProperties: (state, action) => {
         let filtered = state.realestate.filter( el => el.located.includes(action.payload))
         return {...state, filtered:filtered}
    }
    },  
    extraReducers: (builder) => {

        builder.addCase(getRealEstates.pending, (state) => {
            state.isLoading = true
        })
        builder.addCase(getRealEstates.fulfilled, (state, action) => {
            state.isLoading = false
            state.isSuccess = true
            state.realestate = action.payload
            state.filtered = action.payload
        })
        builder.addCase(getRealEstates.rejected, (state, action) => {
            state.isLoading = false
            state.isError = true
            state.message = action.payload
        })
    }
})

export const { filteredProperties, reset } = estateSlice.actions
export default estateSlice.reducer

Select category component

const CategorySelect = () => {

const dispatch = useDispatch()

const changeSearch = (value) => {
    dispatch(filteredProperties(value.value))
}

return (
    <div className="selectMenus">
        <div className="select">search options</div>
        <Select theme={customTheme} options={regions} placeholder="Region" className="selectBox" onChange={changeSearch}  name={'Region'} />
    </div>
    )
}

export default CategorySelect

List component:

    const realestates = useSelector(state => state.realestate)
    let { isLoading, realestate, filtered, isError, message, isSuccess} = realestates;


    useEffect(() => {
        dispatch(getRealEstates())
        if (realestate) {
            setShow(true)
        } else {
            console.log('No data retrieved')
        }
    }, [dispatch])


    // pagination 
    const pageNumbers = []
    const resultsPerPage = 4
    const pages = Math.ceil(realestate.length / resultsPerPage)

    for (let i = 1; i <= pages; i++) {
        pageNumbers.push(i)
    }

    const pagination = (number) => {
        setCurrentNumber(number)
    }
    const slicedList = useCallback(() => {
        const data2 = realestate.slice(((currentNumber - 1) * resultsPerPage), (currentNumber * resultsPerPage))
        setNewList(data2)
    }, [currentNumber, realestate, resultsPerPage])

    useEffect(() => {
        slicedList()
    }, [slicedList])

    return (
        <>
            <div className="borderTop">
                <div className="border"></div>
            </div>
            <div className="sidebarContentWrapper">
               <div className="sidebar"></div>
                  <div className="content2">
                     <CategorySelect />
                         <ListItems newList={newList} show={show}/>

                        <div className="btns">
                        {pageNumbers.map(number => {
                            return <Pagination key={number} active={number === currentNumber} onClick={() => pagination(number)} title={number} />

                        })}
                    </div>
                  </div>
                <div className="sidebar2"></div>
            </div>
        </>
    )
}

export default Content
1 Answers

Problem solved. I had to set a condition in the slicedList function. If the length of the filtered list is less than resultsPerPage the slice method didn't work.
Works fine like this:

 const slicedList = useCallback(() => {
        if (filtered.length > resultsPerPage){
            const data2 = filtered.slice(((currentNumber - 1) * resultsPerPage), (currentNumber * resultsPerPage))
            setNewList(data2)
        }
        if (filtered.length <= resultsPerPage){
            setNewList(filtered)
        }
    }, [currentNumber, filtered, resultsPerPage])
Related