Best way to reorder a list realtime in React-Redux

2019-07-13 06:09发布

问题:

I'm currently build an app that have a realtime list. the view of list as bellow picture:

This list will be updated realtime, when one of these actions is trigger:

  • A message is updated, the updated_time will be changed
  • Receive new message
  • Receive unread status of message

So I want to sort this list base on two conditions:

  1. All unRead_message allways at the top
  2. All message should be sorted by updated_time DESC (newest first), except unread_message always in prioty.

The data of this list is controled by these reduceres:

    export const data = createReducer(
    {},
    {
        [ CONVERSATIONS_RECEIVE ]: ( state, { conversations } ) => {
            return reduce(
                conversations,
                ( memo, conversation ) => {
                    const { id } = conversation.data;

                    if ( memo === state ) {
                        memo = { ...memo };
                    }

                    memo[ id ] = conversation;
                    return memo;
                },
                state
            );
        },
        [ RECEIVED_PENDING_MESSAGE ]: ( state, { data } ) => {

            if ( !data || !data.conversation_id in state ) return state;

            return update( state, {
                [ data.conversation_id ]: { data: { $merge: { snippet: data.message, updated_time: data.created_time } } }
            } )
        },
        [ RECEIVED_CONVERSATION_SEEN ]: ( state, { data } ) => {
            if ( !data || !data.conversation_id in state ) return state;

            return update( state, {
                [ data.conversation_id ]: { data: { $merge: { seen: true } } }
            } )
        },
        [ RECEIVED_CONVERSATION_UNSEEN ]: ( state, { data } ) => {
            if ( !data || !data.conversation || !data.conversation.id in state ) return state;

            return update( state, {
                [ data.conversation.id ]: { data: { $merge: { seen: false } } }
            } )
        },
    }
);

export function keys( state = [], action ) {
    switch ( action.type ) {
        case CONVERSATIONS_RECEIVE:
            if ( !action.conversations || !action.conversations.length ) return state;
            return state.concat( action.conversations.map( conversation => conversation.data.id ) );
        default:
    }

    return state;
}

export default combineReducers( {
    keys,
    data,
    isRequesting,
} );

The list data rendered by an array of keys:

[
  "id_1",
  "id_2",
  //....
]

and the data:

[
    {
        "data": {
            "can_comment": false,
            "can_hide": false,
            "can_like": false,
            "can_reply": true,
            "can_reply_privately": false,
            "comment_id": "",
            "id": "hbiocjgwxpncbnja8a3rra4oke",
            "is_hidden": false,
            "is_private": false,
            "last_seen_by": "ckj7mny56jrmir4df8h466uk7a",
            "message": "",
            "page_id": "1651651651651651",
            "post_id": "",
            "private_reply_conversation": "null",
            "scoped_thread_key": "t_1221211454699392",
            "seen": true,
            "snippet": "