2

I've got a problem with re-rendering table in React.
So at first is how it looks like link
When I fetch data from SWAPI (I'm doing it in action) and passing it into reducer, it works fine and table component re-renders without any trouble.
But when I'm trying to sort it via SORT_RESULTS reducer, it just doesn't do anything with table itself. It actually modifies state as FETCH_DATA reducer do, but doesn't do anything, however I can log sorted information and make sure it was sorted as intended.
Thanks in advance for your help!

// actions.ts
export const onDataFetched = (currentPage: number = 1) => (
    async (dispatch:any) => {
        let data: {} = await fetch(`http://swapi.dev/api/people/?page=${currentPage}`)
                              .then(response => response.json())
        const dataToReturn = {
            type: 'FETCH_DATA',
            payload: data
        }
        dispatch(dataToReturn)
    }
)

// reducers.ts
case FETCH_DATA:
    // returns new state object
    return {
        ...state,
        swapi_data: {
            ...action.payload
        }
    }
// actions.ts
export const onSortResults = (payload: string) => (
    (dispatch:any) => {
        dispatch({type: 'SORT_RESULTS', payload})
    }
)

// reducers.ts
case SORT_RESULTS:
    let results = state.swapi_data.results;
    // title is heading of a table column (e.g. 'name', 'weight', etc)
    const title = action.payload;
    
    // sorts array with persons (objects)
    results.sort((a: any, b: any) => {
        return (a[title] > b[title]) ? 1 : ((b[title] > a[title]) ? -1 : 0)
    })

    // as in example with FETCH_DATA reducers it's doing the same job - returns new state object
    return {
        ...state,
        swapi_data: { 
            ...state.swapi_data,
            results: results,
        },
    }
1
  • 1
    sort() method sorts the array in place, meaning it mutates the original array Commented Aug 10, 2020 at 8:03

1 Answer 1

4

Array Sort Mutates

If you mutate there is no change detected since the reference is the same. But sort also returns itself so you can add this code. The spread operator makes a copy and there for changes the reference meaning that your changes will be detected.

const sortedResults = results.sort((a: any, b: any) => {
  return (a[title] > b[title]) ? 1 : ((b[title] > a[title]) ? -1 : 0)
})

return {
        ...state,
        swapi_data: { 
            ...state.swapi_data,
            results: [...sortedResults],
        },
    }
Sign up to request clarification or add additional context in comments.

1 Comment

No problem Omer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.