in react app, using few libraries (i.e. material ui , react intl) pass react elements props higher-level components down "dumb components" have 1 job: render.
smart component:
import actionexplore 'material-ui/svg-icons/action/explore'; import { formattedmessage } 'react-intl'; export class smartcomponent extends component { render() { return ( <div> <dumbcomponent text={<formattedmessage id="en.dumbcomponent.text" />} icon={<actionexplore/>} /> <anotherdumbcomponent {props.that.are.changing} /> </div> ); } }
dumb component:
import shallowcompare 'react-addons-shallow-compare'; export class dumbcomponent extends component { shouldcomponentupdate(nextprops, nextstate) { return shallowcompare(this, nextprops, nextstate); } render() { return ( <div> <h1>{this.props.text}</h1> {this.props.icon} </div> ); } }
the benefit of doing this, dumbcomponent not need know application logic (material ui, internationalization, etc.). renders, leaving smartcomponent take care of business logic.
the downside encountering approach performance: dumbcomponent always re-render, when anotherdumbcomponent's props change instead of own, because shouldcomponentupdate
always returns true
. shouldcomponentupdate
unable accurate equality check between react elements in above example.
how can react elements equality-checked in shouldcomponentupdate
? costly perform? passing react elements props dumb components bad idea? possible not pass down react elements props, yet keep components dumb? thanks!
whether performant or not going depend on use case. rule of thumb, think kind of logic best used when expect user input impact children of "dumb component", rather it's peers.
as example, material-ui's dialog has identical structure suggest it's action buttons , title. (https://github.com/callemall/material-ui/blob/master/src/dialog/dialog.js#l292). works in case because elements on modal, doesn't modify unless opening or closing it.
as potential workaround, if passed in objects needed create children elements, without passing in entire element? haven't tried this, i'm not sure how work, might worth try. extent of;
<dumbcomponent textcomponent={formattedmessage} textprops={{id: "en.dumbcomponent.text"}}/> //in dumbcomponent; render(){ return ( <div> <h1> <this.props.textcomponent {...this.props.textprops}/> </h1> </div> ); }
might give more concrete things play around when determining if should update or not.