From 83b878be7da8f3d2857a9b132ed5ee547708b0f6 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 11 Jul 2016 22:11:04 +0200 Subject: [PATCH] Added tests and updated docs to address #50 --- README.md | 3 +++ test/misc.js | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 test/misc.js diff --git a/README.md b/README.md index f5d7cd50..75c25c29 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,9 @@ const TodoView = observer(React.createClass({ const TodoView = observer(({todo}) =>
{todo.title}
) ``` +It is possible to set a custom `shouldComponentUpdate`, but in general this should be avoid as MobX will by default provide a highly optimized `shouldComponentUpdate` implementation, based on `PureRenderMixin`. +If a custom `shouldComponentUpdate` is provided, it is consulted when the props changes (because the parent passes new props) or the state changes (as a result of calling `setState`), but if an observable used by the rendering is changed, the component will be re-rendered and `shouldComponent` is not consulted. + ### `componentWillReact` (lifecycle hook) React components usually render on a fresh stack, so that makes it often hard to figure out what _caused_ a component to re-render. diff --git a/test/misc.js b/test/misc.js new file mode 100644 index 00000000..755b6e33 --- /dev/null +++ b/test/misc.js @@ -0,0 +1,73 @@ +var React = require('react'); +var enzyme = require('enzyme'); +var mount = enzyme.mount; +var mobx = require('mobx'); +var observer = require('../').observer; +var Provider = require('../').Provider; +var test = require('tape'); +var e = React.createElement; + +test('custom shouldComponentUpdate is not respected for observable changes (#50)', t => { + var called = 0; + var x = mobx.observable(3) + var C = observer(React.createClass({ + render: function() { + return e("div", {}, "value:" + x.get()); + }, + shouldComponentUpdate() { + called++; + } + })); + + const wrapper = mount(e(C)); + t.equal(wrapper.find("div").text(), "value:3"); + t.equal(called, 0) + x.set(42); + t.equal(wrapper.find("div").text(), "value:42"); + t.equal(called, 0) + + t.end(); +}) + +test('custom shouldComponentUpdate is not respected for observable changes (#50)', t => { + var called = 0; + var y = mobx.observable(5) + + var C = observer(React.createClass({ + render: function() { + return e("div", {}, "value:" + this.props.y); + }, + shouldComponentUpdate(nextProps) { + called++; + return nextProps.y !== 42; + } + })); + + var B = observer(React.createClass({ + render: function() { + return e("span", {}, e(C, {y: y.get()})); + }, + shouldComponentUpdate() { + called++; + } + })); + + + const wrapper = mount(e(B)); + t.equal(wrapper.find("div").text(), "value:5"); + t.equal(called, 0) + + y.set(6); + t.equal(wrapper.find("div").text(), "value:6"); + t.equal(called, 1) + + y.set(42) + t.equal(wrapper.find("div").text(), "value:6"); // not updated! + t.equal(called, 2) + + y.set(7) + t.equal(wrapper.find("div").text(), "value:7"); + t.equal(called, 3) + + t.end(); +})