Improving performance with selectorsΒΆ
Example using reselect:
/// selectors.js
import { db as myDb } from './schema';
import { createSelector, createStructuredSelector } from 'reselect';
// Single table, all records, no relations
export const selectAllPosts = createSelector(
({ db }) => db.BlogPost,
(table) => {
return myDb.selectTable(table).values; // NB. should be converted to a view model.
}
);
// using a structured selector, makes us select only the tables we want
const blogPostAndRels = createStructuredSelector({
posts: ({ db }) => db.BlogPost,
comments: ({ db }) => db.Comment,
users: ({ db }) => db.User
});
// multiple complex models
export const selectAllPosts = createSelector(
blogPostAndRels,
(tables) => {
// get the TableModel
const { BlogPost } = myDb.selectTables(tables);
return BlogPost.all().map(_serializePost);
}
);
// single complex model by id
export const selectPost = createSelector(
blogPostAndRels,
(state, props) => props.postId,
(tables, id) => {
// get the TableModel
const { BlogPost } = myDb.selectTables(tables);
// get the Record by id
const postModel = BlogPost.getOrDefault(id);
return postModel && _serializePost(postModel);
}
);
const _serializePost = (post) => {
return {
...post.value,
numComments: post.comments.length,
author: post.author.value.name
};
};
Using selectors we can improve the previous example:
import { Component } from "react";
import { connect } from "react-redux";
import { db } from "./schema";
import { selectAllPosts } from "./selectors";
class PostListComponent extends Component {
render() {
return <table>
<tbody>
{this.props.posts.map(post => (
<tr>
<td>{post.title}</td>
<td>{post.author}</td>
<td>{post.numComments}</td>
</tr>
) }
</tbody>
</table>;
}
}
const mapStateToProps = (state, ownProps) => {
return {
posts: selectAllPosts( state )
};
};
export const PostList = connect(mapStateToProps)(PostListComponent);