Reputation: 16416
I have an app that receives data from Firebase as such:
const projectsRef = fire.database().ref('projects').orderByKey().limitToLast(limit);
projectsRef.on('child_added', (snapshot) => {
const project = { ...snapshot.val(), id: snapshot.key };
console.log(project);
this.setState(prevState => ({
...prevState,
projects: [...prevState.projects, project],
}));
});
I have a hundred records, the listener above is invoked one hundred times, and the ProjectsTable component is re-rendered with a call to the component's render() method one hundred times. That's all fine and dandy, but I don't actually see the data showing up in the ProjectsTable on the screen until all that is complete and then another delay of about two seconds.
Why isn't the screen being redrawn after each render() call to the component with the updated data and how do I fix that?
Upvotes: 1
Views: 315
Reputation: 16416
The problem is that JavaScript is single-threaded, so calling render() every 10ms is a terrible idea. It's best to only call setState (which invoked render) once after all the data is received and not after each record is received. So I set a timer of 100ms to invoke render() - and the timer is reset every time another record comes in. The data finishes loading very quickly - and then with only one call to render() the result is displayed on the screen. Very fast!
const projectsRef = fire.database().ref('projects').orderByKey().limitToLast(limit);
projectsRef.on('child_added', (snapshot) => {
const project = { ...snapshot.val(), id: snapshot.key };
this.projects.push(project);
clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.setState(prevState => ({
...prevState,
projects: this.projects,
}));
}, 100);
});
Upvotes: 1