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

inject-context

v1.1.2

Published

Avoid unnecessary re-rendering of components caused by changes in context value

Downloads

8

Readme

通过 selector 结合 React.memo 来解决 context 重渲染的性能问题

使用方式

npm install inject-context

单个 context

import React from 'react';
import injectContext from 'inject-context';

const MyContext = React.createContext({ count: 0 });

const App = props => {
  // context的count被注入到props中
  return <div>{props.count}</div>;
};

const Componnet = injectContext({
  context: MyContext,
  selector: s => ({ count: s.count }),
})(App);

多个 context

import React from 'react';
import injectContext from 'inject-context';

const MyContext1 = React.createContext({ count: 0 });
const MyContext2 = React.createContext({ count: 0 });

const App = props => {
  return <div>{props.count1 + props.count2}</div>;
};

const Componnet = injectContext([
  {
    context: MyContext1,
    selector: s => ({ count1: s.count }),
  },
  {
    context: MyContext2,
    selector: s => ({ count2: s.count }),
  },
])(App);

效果

组件重渲染,dom 会高亮,图中 count 会被改变,someString 不会被改变

源代码中 npm run demo 可以运行该 demo

20240410100632.gif

支持深度比较

inject-contex 使用 memo 来达到避免不必要渲染的目的,memo 默认的比较函数只对比第一层属性,也就是对于 memo 来说,下面两个 props 是不同的:

const prevProps = {
  obj: { key: 1 },
};
const newProps = {
  obj: { key: 1 },
};

inject-context 扩展了 memo 的默认比较函数,支持选择性的深度比较,如果选择的某个 context 状态想要深度比较的话,可以通过如下方式:

const InjectContextChild2 = injectContext<{
  someString: ContextValue['someString'];
}>({
  context: Context,
  selector: s => ({ obj: s.obj }),

  // selector返回的对象的键
  deepKeys: ['obj']
})(....);

指定deepKeys来告诉 inject-context 你需要深度比较的属性,值就是 selector 返回的对象的键名。

注意,不要滥用这个特性,深度比较带来的开销可能大于重渲染的开销。

TS 支持

props 类型提示

image.png

count 实际被注入到 props 里了,但是并没有良好的类型提示,可以通过给 inject-context 传泛型解决,它能接收两个泛型,第一个是注入的值的类型,第二个是原本 props 的类型。

image.png

selector 参数类型

默认的 selector 参数是 any,没有良好的类型提示

image.png

可以通过 inject-context 提供的 defineSelector 来提供类型提示。 用 defineSelector 包裹一下传入的 selector 属性即可。

image.png

写在最后

介绍文章