npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

renorm

v0.3.9

Published

Avoid React avoidable re-renders with Redux, Reselect and Normalizr using an optimisied selector.

Downloads

5

Readme

Renorm

A state selector to optimize the usage of React, Redux, Reselect & Normalizr.

CircleCI Status Coverage Status Maintainability minzipped size npm version GitHub license

Table of Contents

Motivation

An avoidable re-render happens when a React component receives a shallow copy of one of it's properties, however the object didn't "really" change. Meaning A deep comparison of all of the object's primitives would find them identical. This causes a React component to run it's render method needlessly, since the render result would be identical to the last one.

Solution

Documentation

Installation

yarn add renorm
npm install --save renorm

Features

  • Discovers entities used in your selector automatically.
  • Significant performance boost when selecting a list of entities.
  • Developer friendly syntax.

How It Works

renorm(inputSelector, schema) When you create a renorm selector this is what happens:

  1. A new reselect selectorCreator is created with the schema you provided. Renorm uses a customized version of Reselect's defaultMemoize optimized for normalizr entities.
  2. Renorm traverses the schema you provided and saves all unique entities found.
  3. Renorm creates an entities selector with only the relevant schema entities
  4. Renorm now uses the Reselect selector creator from #1 which uses input, schema and relevant entities to invoke Normalizr's denormalize method. This is the return value when invoking renorm

Memoization Strategy

Renorm has a two phase memoization strategy

Basic Memoization. Based on Reselect's existing defaultMemoize

  1. Check arguments length and null check
  2. Shallow equality of of the input ids and each one of the relevant entity maps (stocks, companies, etc.) if all the checks return true the memoized version is returned, otherwise the function is invoked. This the exact same process Reselect already does by default.

if the function is invoked Renorm switches to advanced memoization

Advanced Memoization

For each the denormalized object, check all underlying entities:

  1. If all underlying entities are shallowly equal to the previous ones, return previous denormalized object.
  2. Else return the denormalized object
  3. Cache results for next run

The big advantage here is that only newly returned objects will trigger React's render. Without Renorm's advanced memoization every item on the list would trigger React's render, even if you only a single entity was changed!

Examples

Basic Usage

// schema
import { schema } from 'normalizr';
const stockSchema = new schema.Entity('stocks');
const companySchema = new schema.Entity('companies', {
  stock: stockSchema,
});
export const Schemas = {
  STOCK: stockSchema,
  STOCK_ARRAY: [stockSchema],
  COMPANY: companySchema,
  COMPANY_ARRAY: [companySchema],
};

// redux state
const state = {
  companyIds: ['COMP_A', 'COMP_B', 'COMP_C' /*...*/],

  entities: {
    companies: {
      /*company entities...*/
    },
  },
  stocks: {
    /*stock entities...*/
  },
};

//renorm selector
import renorm from 'renorm';
const getCompanyIds = (state) => state.companyIds;
const getCompanies = renorm(getCompanyIds, Schemas.COMPANY_ARRAY);

For comparison, here's the same selector without using renorm:

import { denormalize } from 'normalizr';
import { createSelector } from 'reselect';
const getCompanyIds = (state) => state.companyIds;
const getCompanyEntities = (state) => state.entities.companies;
const getStockEntities = (state) => state.entities.stocks;
export const getCompanies = createSelector(
  getCompanyIds,
  getCompanyEntities,
  getStockEntities,
  (stockList, companies, stocks) =>
    denormalize(stockList, Schemas.COMPANY_ARRAY, {
      companies,
      stocks,
    })
);

Performance

Options

Renorm's third parameter is an optional options object that contains the following props:

| Name | Type | Default Value | Description | | ------------ | -------- | ------------------ | --------------------------------------------------------------------- | | entitiesPath | string | "entities" | Path to the entities object in the state | | process | function | (result) => result | A function to perform mutation operations before results are returned |

Dependencies

License

MIT