├── .babelrc
├── .eslintrc
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── package.json
├── scripts
└── build
└── src
├── component.js
├── function.js
├── index.js
├── mixin.js
└── shallowEqual.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "stage": 0,
3 | "loose": ["es6.modules", "es6.classes"]
4 | }
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "node": true,
5 | "mocha": true
6 | },
7 | "parser": "babel-eslint",
8 | "rules": {
9 | "quotes": [2, "single"],
10 | "eol-last": [0],
11 | "no-mixed-requires": [0],
12 | "no-underscore-dangle": [0],
13 | "consistent-return": [0],
14 | "strict": [0, "never"]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 |
4 | # Build products
5 | component.js
6 | function.js
7 | index.js
8 | mixin.js
9 | shallowEqual.js
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src
2 | scripts
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Dan Abramov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # No Maintenance Intended
2 |
3 | [](http://unmaintained.tech/)
4 |
5 |
6 |
7 | This project is no longer actively maintained. It does its job, but there are no plans to extend or change it.
8 | We suggest you to use the official [`react-addons-shallow-compare`](https://facebook.github.io/react/docs/shallow-compare.html) package instead which does the same job. To wrap functional components in a more expressive way, we encourage you to check out [`recompose`](https://github.com/acdlite/recompose#optimize-rendering-performance).
9 |
10 |
11 | # react-pure-render
12 |
13 | A function, a component and a mixin for React pure rendering.
14 |
15 | This module provides *exactly* the same functionality as [PureRenderMixin](https://facebook.github.io/react/docs/pure-render-mixin.html), but as a standalone module and in three different flavors.
16 |
17 | ### Usage
18 |
19 | #### Function
20 |
21 | This is my preferred method, but it requires ES7 [class property transform](https://gist.github.com/jeffmo/054df782c05639da2adb) to be enabled by putting `{ "stage": 0 }` in your [.babelrc](https://babeljs.io/docs/usage/babelrc/).
22 |
23 | ```js
24 | import { Component } from 'react';
25 | import shouldPureComponentUpdate from 'react-pure-render/function';
26 |
27 | export default class Button extends Component {
28 | shouldComponentUpdate = shouldPureComponentUpdate;
29 |
30 | render() { }
31 | }
32 | ```
33 |
34 | #### Component
35 |
36 | Inheritance is not very cool but it doesn't hurt a lot if it's just for the sake of this single method. If you don't want to use stage 0 transforms, you can use a base class instead:
37 |
38 | ```js
39 | import PureComponent from 'react-pure-render/component';
40 |
41 | export default class Button extends PureComponent {
42 | render() { }
43 | }
44 | ```
45 |
46 | #### Mixin
47 |
48 | If you're working with `createClass`-style components, use the mixin. It's exactly the same as [`React.addons.PureRenderMixin`](https://facebook.github.io/react/docs/pure-render-mixin.html).
49 |
50 | ```js
51 | var React = require('react');
52 | var PureMixin = require('react-pure-render/mixin');
53 |
54 | var Button = React.createClass({
55 | mixins: [PureMixin],
56 |
57 | render: function () { }
58 | });
59 |
60 | module.exports = Button;
61 | ```
62 |
63 | #### shallowEqual
64 |
65 | Sometimes `shallowEqual` is all you need. It's bad to reach out into React internals, so this library exposes exactly the same `shallowEqual` you already know and love from React.
66 |
67 | ```js
68 | import shallowEqual from 'react-pure-render/shallowEqual';
69 | console.log(shallowEqual({ x: 42 }, { x: 42 }));
70 | ```
71 |
72 | ### Known Issues
73 |
74 | If a component in the middle of your rendering chain has pure rendering, but some nested component relies on a `context` change up the tree, **the nested component won't learn about `context` change and won't update**. This is a [known React issue](https://github.com/facebook/react/issues/2517) that exists because `context` is an [experimental](https://facebook.github.io/react/docs/context.html) feature and is not finished. However some React libraries already rely on `context`, for example, [React Router](https://github.com/rackt/react-router). My suggestion for now is to use pure components in apps relying on such libraries very carefully, and only use pure rendering for leaf-ish components that are known *not* to rely on any parent `context`.
75 |
76 | ### Further Reading
77 |
78 | * [PureRenderMixin](https://facebook.github.io/react/docs/pure-render-mixin.html)
79 | * [Advanced Performance](https://facebook.github.io/react/docs/advanced-performance.html)
80 |
81 | ### License
82 |
83 | MIT
84 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-pure-render",
3 | "version": "1.0.2",
4 | "description": "A function, a component and a mixin for React pure rendering",
5 | "main": "index.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "https://github.com/gaearon/react-pure-render.git"
9 | },
10 | "scripts": {
11 | "build": "./scripts/build",
12 | "prepublish": "npm run build"
13 | },
14 | "keywords": [
15 | "react",
16 | "pure",
17 | "render",
18 | "shouldComponentUpdate",
19 | "optimization",
20 | "performance"
21 | ],
22 | "author": "Dan Abramov (http://github.com/gaearon)",
23 | "license": "MIT",
24 | "bugs": {
25 | "url": "https://github.com/gaearon/react-pure-render/issues"
26 | },
27 | "homepage": "https://github.com/gaearon/react-pure-render",
28 | "devDependencies": {
29 | "babel": "^5.2.9",
30 | "babel-eslint": "^3.0.1",
31 | "eslint": "^0.20.0"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/scripts/build:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | ./node_modules/.bin/babel src --out-dir .
--------------------------------------------------------------------------------
/src/component.js:
--------------------------------------------------------------------------------
1 | import shouldPureComponentUpdate from './function';
2 | import { Component } from 'react';
3 |
4 | export default class PureComponent extends Component {}
5 | PureComponent.prototype.shouldComponentUpdate = shouldPureComponentUpdate;
6 |
--------------------------------------------------------------------------------
/src/function.js:
--------------------------------------------------------------------------------
1 | import shallowEqual from './shallowEqual';
2 |
3 | export default function shouldPureComponentUpdate(nextProps, nextState) {
4 | return !shallowEqual(this.props, nextProps) ||
5 | !shallowEqual(this.state, nextState);
6 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export shallowEqual from './shallowEqual';
2 | export shouldPureComponentUpdate from './function';
3 | export PureComponent from './component';
4 | export PureMixin from './mixin';
--------------------------------------------------------------------------------
/src/mixin.js:
--------------------------------------------------------------------------------
1 | import shouldPureComponentUpdate from './function';
2 |
3 | export default {
4 | shouldComponentUpdate: shouldPureComponentUpdate
5 | };
--------------------------------------------------------------------------------
/src/shallowEqual.js:
--------------------------------------------------------------------------------
1 | export default function shallowEqual(objA, objB) {
2 | if (objA === objB) {
3 | return true;
4 | }
5 |
6 | if (typeof objA !== 'object' || objA === null ||
7 | typeof objB !== 'object' || objB === null) {
8 | return false;
9 | }
10 |
11 | var keysA = Object.keys(objA);
12 | var keysB = Object.keys(objB);
13 |
14 | if (keysA.length !== keysB.length) {
15 | return false;
16 | }
17 |
18 | // Test for A's keys different from B.
19 | var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);
20 | for (var i = 0; i < keysA.length; i++) {
21 | if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) {
22 | return false;
23 | }
24 | }
25 |
26 | return true;
27 | }
--------------------------------------------------------------------------------