diff --git a/docs/autoredraw.md b/docs/autoredraw.md new file mode 100644 index 00000000..ec4c5945 --- /dev/null +++ b/docs/autoredraw.md @@ -0,0 +1,120 @@ +# The auto-redraw system + +Mithril implements a virtual DOM diffing system for fast rendering, and in addition, it offers various mechanisms to gain granular control over the rendering of an application. + +When used idiomatically, Mithril employs an auto-redraw system that synchronizes the DOM whenever changes are made in the data layer. The auto-redraw system becomes enabled when you call `m.mount` or `m.route` (but it stays disabled if your app is bootstrapped solely via `m.render` calls). + +The auto-redraw system simply consists of triggering a re-render function behind the scenes after certain functions complete. + +### After event handlers + +Mithril automatically redraws after DOM event handlers that are defined in a Mithril view: + +```javascript +var MyComponent = { + view: function() { + return m("div", {onclick: doSomething}) + } +} + +function doSomething() { + //a redraw happens synchronously after this function runs +} + +m.mount(document.body, MyComponent) +``` + +You can disable an auto-redraw for specific events by setting `e.redraw` to `false`. + +```javascript +var MyComponent = { + view: function() { + return m("div", {onclick: doSomething}) + } +} + +function doSomething(e) { + e.redraw = false + // no longer triggers a redraw when the div is clicked +} + +m.mount(document.body, MyComponent) +``` + + +### After m.request + +Mithril automatically redraws after [`m.request`](request.md) completes: + +```javascript +m.request("/api/v1/users").then(function() { + //a redraw happens after this function runs +}) +``` + +You can disable an auto-redraw for a specific request by setting the `background` option to true: + +```javascript +m.request("/api/v1/users", {background: true}).then(function() { + //does not trigger a redraw +}) +``` + + +### After route changes + +Mithril automatically redraws after [`m.route.set()`](route.md#routeset) calls (or route changes via links that use [`m.route.link`](route.md#routelink) + +```javascript +var RoutedComponent = { + view: function() { + return [ + // a redraw happens asynchronously after the route changes + m("a", {href: "/", oncreate: m.route.link}), + m("div", { + onclick: function() { + m.route.set("/") + } + }), + ] + } +} + +m.route(document.body, "/", { + "/": RoutedComponent, +}) +``` + +--- + +### When Mithril does not redraws + +Mithril does not redraw after 3rd party library event handlers. In those cases, you must manually call [`m.redraw()`](redraw.md). + +Mithril also does not redraw after lifecycle methods. This is because lifecycle methods run within the redraw cycle and allowing a nested redraw to run could cause loss of stability or even stack overflows. If you need to trigger a redraw within a lifecycle method, you should call `m.redraw` from within the callback of an asynchronous function such as `requestAnimationFrame`, `Promise.resolve` or `setTimeout`. + +```javascript +var StableComponent = { + oncreate: function(vnode) { + vnode.state.height = vnode.dom.offsetHeight + requestAnimationFrame(function() { + m.redraw() + }) + }, + view: function() { + return m("div", "This component is " + vnode.state.height + "px tall") + } +} +``` + +Mithril does not auto-redraw vnode trees that are rendered via `m.render`. This means redraws do not occur after event changes and `m.request` calls for templates that were rendered via `m.render`. Thus, if your architecture requires manual control over when rendering occurs (as can sometimes be the case when using libraries like Redux), you should use `m.render` instead of `m.mount`. + +Remember that `m.render` expects a vnode tree, and `m.mount` expects a component: + +```javascript +// wrap the component in a m() call for m.render +m.render(document.body, m(MyComponent)) + +// don't wrap the component for m.mount +m.mount(document.body, MyComponent) +``` diff --git a/docs/guides.md b/docs/guides.md index d2bd87da..1e05cc3b 100644 --- a/docs/guides.md +++ b/docs/guides.md @@ -9,6 +9,7 @@ - [Components](components.md) - [Lifecycle methods](lifecycle-methods.md) - [Keys](keys.md) + - [Autoredraw system](autoredraw.md) - Social - [Community chat](https://gitter.im/lhorie/mithril.js) - [Mithril Jobs](https://github.com/lhorie/mithril.js/wiki/JOBS)