jurassix / react-immutable-render-mixin Goto Github PK
View Code? Open in Web Editor NEWreact pure render mixin for facebook/immutable-js library
License: MIT License
react pure render mixin for facebook/immutable-js library
License: MIT License
Hello,
I found this open source from a link in a blog some days before. The blog said this repo is very helpful for performance.
Currently, my project use Immutable & PureComponent, and use Immutable.is() in componentShouldUpdate func to check if need re-render in each component. So if I try to use "react-immutable-render-mixin" in my project, will it lead to some benefit?
Could you simply clarify that how this repo do within the componentShouldUpdate or other
implementation?
I know that users are urged to use PureComponent, but I still want to know some deep implement here in "react-immutable-render-mixin", and know why "urged to use PureComponent" and what is the diff?
Many thx
Hi Clint, first off let me thank you for open-sourcing this useful library!
I'm fairly new to React (Immutable specifically) and I was having trouble wrapping my head around using Immutable to improve my app performance. Specifically, what I'm not understanding is in what cases does the ===
equality holds and in what cases would Immutable.is
is required.
From the docs
So, Immutable data structures provides you a cheap and less verbose way to track changes on objects, which is all we need to implement shouldComponentUpdate. Therefore, if we model props and state attributes using the abstractions provided by immutable-js we'll be able to use PureRenderMixin and get a nice boost in perf.
However, in my tests I've found this to be not quite true (as a result of which I found this repo).
var Block = Immutable.Record({
id: 0,
questions: Immutable.List(),
subblocks: Immutable.List(),
randomizable: true,
ordering: false
});
var b1 = Block({id: 1});
var b2 = b1.set('randomizable', false);
var b3 = b2.set('randomizable', true);
console.log("b1 and b2:", b1 === b2); // returns false
console.log("b1 and b3:", b1 === b3); // also returns false
console.log("b1 and b2:", Immutable.is(b1, b2)); // returns false
console.log("b1 and b3:", Immutable.is(b1, b3)); // returns true
As seen above, it seems that the PureRenderMixin
cannot be used, right? Is that the motivation behind this library? Also, if that is indeed the case, why do the React docs say so?
Thank you for your time!
I think the peer dependency for react may need a version.
With npm 3.7.1 I can start with this package.json:
{
"name": "t",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": { },
"author": "",
"license": "ISC",
"dependencies": {
"immutable": "^3.7.6",
"react": "^0.14.7"
}
}
And run npm install --save react-immutable-render-mixin
It results in:
[email protected] /Users/robmadole/Development/src/FortAwesome/fortawesome/t
├── UNMET PEER DEPENDENCY [email protected]
└── [email protected]
npm WARN [email protected] requires a peer of react@ but none was installed.
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
Projects depending in this mixin will almost always depend on immutablejs. A peerDependency ensures that both (project and mixin) use the same version.
windows10
0.9.7
import {shouldComponentUpdate} from 'react-immutable-render-mixin'
import ReactPullToRefresh from 'react-pull-to-refresh'
let count = 1
class Product extends Component {
constructor(props) {
super(props)
this.shouldComponentUpdate = shouldComponentUpdate.bind(this)
this.state = {
items: [
<div key={'item-' + count}>Item {count++}</div>
]
}
handleRefresh(resolve, reject) {
let self = this
console.log('handleRefresh...', this)
setTimeout(function () {
self.addItem() ? resolve() : reject()
console.log('is true: ', self.addItem())
}, 500)
}
addItem() {
console.log('addItem...')
this.state.items.push(<div key={'item-' + count}>Item {count++}</div>);
this.setState({
items: this.state.items
})
console.log('new items: ', this.state.items)
return true
}
render() {
return (
<div className="content-block">
<ReactPullToRefresh onRefresh={this.handleRefresh.bind(this)} style={{
textAlign: 'center'
}}>
<h3>Pull down to refresh</h3>
<div>
{this.state.items}
</div>
</ReactPullToRefresh>
</div>
)
}
}
}
React state has changed, but ui is not updated when I add react-immutable-render-mixin
I updated to the newest version and get the following error trying to import it
import ImmutableRenderMixin from 'react-immutable-render-mixin';
`Module not found: Error: Cannot resolve module 'react-immutable-render-mixin'``
0.9.2 works fine though.
Hey, I wanted to make sure I understood this bit correctly:
if (objA === objB || is(objA, objB)) {
return true;
}
I don't think you can use Immutable.Map as your entire props/state. is
would then check for referential equality, just like ===
.
For example if you have some code like this:
static readyOnActions = (dispatch, params) => {
return Promise.all([dispatch(landingActions.getLandingInfo())]);
}
That is used to do the server render side is lost in the wrapper.
One posible solution is use 'hoist-non-react-statics'
import React, { Component } from 'react';
import shouldComponentUpdate from './shouldComponentUpdate';
import hoistStatics from 'hoist-non-react-statics'
/**
* Makes the given component "pure".
*
* @param object Target Component.
*/
export default function immutableRenderDecorator(Target) {
class Wrapper extends Component {
render() {
return React.createElement(Target, this.props, this.props.children);
}
}
Wrapper.prototype.shouldComponentUpdate = shouldComponentUpdate;
// don't lost static properties function
// ex. for fetchData
return hoistNonReactStatic(Wrapper, Target);
}
It is fine for you?
The docs don't really explain the difference between this library and PureRenderMixin. Could you clarify for me please?
Any plans for adding a support for the functional components for immutableRenderDecorator
?
import logo from './logo.png';
const Logo = () => <img src={logo} />;
export default immutableRenderDecorator(Logo);
As a micro-nano optimization, how about to check state
before props
?
From my perspective state
is what changed more frequently and is more likely to change.
Yep, I understand it's pretty much subjective, but I think it worth mentioning.
Hello,
Couple of weeks ago I was going to use this library when I saw your warning.
Can you explain this line?
This library was created from experimentations with Immutable that were ultimately erroneous; improper usage of Immutable.js 💩.
Also there is something else that you could clarify for me.
Right now I often have shouldComponentUpdate()
that looks like this:
private shouldComponentUpdate(newProps, newState) {
const propsChanged = !Immutable.is(this.props.referentiel, newProps.referentiel)
|| this.props.multipleMode !== newProps.multipleMode
|| this.props.groupIsVisible !== newProps.groupIsVisible
|| this.props.searchButtonLabel !== newProps.searchButtonLabel
|| this.props.searchButtonClassName !== newProps.searchButtonClassName
|| this.props.forceSearchButtonDisabled !== newProps.forceSearchButtonDisabled
|| this.props.isFetchingForDisplay !== newProps.isFetchingForDisplay
|| this.props.isFetchingForSearch !== newProps.isFetchingForSearch
|| this.props.defaultSelection !== newProps.defaultSelection
|| this.props.onChange !== newProps.onChange
|| this.props.onSearchSubmit !== newProps.onSearchSubmit;
const stateChanged = !Immutable.is(this.state.phaseRefIds, newState.phaseRefIds)
|| !Immutable.is(this.state.groupIds, newState.groupIds)
|| !Immutable.is(this.state.phaseIds, newState.phaseIds)
|| !Immutable.is(this.state.updperIds, newState.updperIds);
return propsChanged || stateChanged;
}
Of course it's tedious, which is why I wanted to use your library. But you say we should use PureRenderMixin.
Question is: are we not supposed to use Immutable.is()
for props using Immutable types? As far as I know PureRenderMixin knows nothing about it. Or maybe it doesn't matter because Immutable makes sure pointers don't change if data doesn't, so a plain triple equals comparison is enough?
To make things clear: is it OK to use PureRenderMixin even with Immutable props?
import React from 'react';
import { immutableRenderDecorator } from 'react-immutable-render-mixin';
class Test extends React.Component {
render() {
return <div></div>;
}
}
export default immutableRenderDecorator(Test);
The function immutableRenderDecorator
doesn't return anything, so this will got a cannot find module
error.
examples
<My value={Immutable.fromJS({value:123}) } onChange={this.handleChange.bind(this)}></My>
this component's props.onChange isn't immutable
so
if (!bHasOwnProperty(keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
return false;
}
may be miss compare mutable data like onChang
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.