React Native Realm DB "objects()" blocks/freeze the UI

1.1k Views Asked by At

I have a JS service whose functions return promises. Those promises uses the Realm DB library. However, whenever my action creators with from React w/ Redux Thunk calls these functions, the UI just freezes. I cannot display the loading circle, the sidebar cannot be pulled out, and the back buttons are not functional until the promise is resolved. Once it does, all the touch presses are queued and executed all at once which makes it chaotic.

If I am missing something fundamental with the asynchronous (or lack thereof) behaviour of Realm DB, please let me know! It would be very much appreciated.!


service.js
export {
    getProjects() {
        return Realm.open({ config.db }).then(db => db.objects("Projects"));
    }
}

action.js (Action Creator)
import Service from "./service";

export {
    getAllProjects() {
        return async dispatch => {
            const allProjects = await Service.getProjects();
            dispatch({
                type: ....,
                payload: allProjects
            })
        }
    }
}

component.js (React Native)
class Component extends ... {

    componentDidMount() {
        this.props.getAllProjects();
    }

    render() {
        const { Projects } = this.props;

        if(Projects.loading) {
            return <LoadingCircle />; // This never gets displayed, even though the Projects.loading yields "true".
        }
        
        return JSON.stringify(this.props.Projects);
    }
}

I was hoping any fix to this basic thing could fix my problem of the router not being able to animate/transition until the Realm DB finishes, plus the user inputs being queued.

I have tried using Axios to make a big long request to see if it would yield the same problems. However, it seems that it only happens on Realm DB, as Axios does not seem to block the UI.

1

There are 1 best solutions below

2
On

I think your issue is how you are opening it. Realm.open isn't a promise, it returns a progress promise.

https://realm.io/docs/javascript/latest/api/Realm.html#.open

e.g. your code could be changed to...

Realm.open(config)
  .progress(() => {/** progress callback here **/} )
  .then(realm => { 
    realm.objects('Projects')
  })

Or rewritten to async/await like your other parts

let progress = Realm.open(config)
let realm = await progress
return realm.objects('Projects')

Or if you want to pass a progress handler you can also do this

let realm = await Realm.open(config).progress(() => {/** progress callback here **/})
return realm.objects('Projects')