From a988276e9b79a4fc3c6fe8137f9a34a65429f8eb Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Fri, 8 Jul 2016 10:24:48 -0400 Subject: [PATCH] Revert "don't copy state anymore" This reverts commit cece44d4ac87c0df1bd627fdba01b2c8581a5235. --- docs/components.md | 24 ++++++++++++++++++++++-- examples/editor-bundle/index.html | 4 +--- examples/editor/index.html | 4 +--- render/tests/test-component.js | 18 ++++++++++++++++++ 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/docs/components.md b/docs/components.md index 3f31a8cb..db68927b 100644 --- a/docs/components.md +++ b/docs/components.md @@ -77,11 +77,31 @@ To learn more about lifecycle methods, [see the lifecycle methods page](lifecycl Like all virtual DOM nodes, component vnodes can have state. Component state is useful for supporting object-oriented architectures, for encapsulation and for separation of concerns. -The state of a component can be accessed two ways: via `vnode.state` and via the `this` keyword in component methods. +The state of a component can be accessed three ways: as a blueprint at initialization, via `vnode.state` and via the `this` keyword in component methods. + +#### At initialization + +Any property attached to the component object is deep-cloned for every instance of the component. This allows simple state initialization. + +In the example below, `data` is a property of the `Input` component's state object. + +```javascript +var ComponentWithInitialState = { + data: "Initial content", + view: function(vnode) { + return m("div", vnode.state.data) + } +} + +m(ComponentWithInitialState) + +// Equivalent HTML +//
Initial content
+``` #### Via vnode.state -State can be accessed via the `vnode.state` property, which is available to all lifecycle methods as well as the `view` method of a component. +State can also be accessed via the `vnode.state` property, which is available to all lifecycle methods as well as the `view` method of a component. ```javascript var ComponentWithDynamicState = { diff --git a/examples/editor-bundle/index.html b/examples/editor-bundle/index.html index ef3cc014..2fee9688 100644 --- a/examples/editor-bundle/index.html +++ b/examples/editor-bundle/index.html @@ -19,9 +19,7 @@ h1,h2,h3,h4,h5,h6,p {margin:0 0 10px;} var m = require("../../mithril") var Editor = { - oninit: function() { - this.data = "# Markdown Editor\n\nType on the left panel and see the result on the right panel" - }, + data: "# Markdown Editor\n\nType on the left panel and see the result on the right panel", view: function(vnode) { return [ m("textarea.editor-input", {oninput: function(e) {vnode.state.data = e.target.value}}, vnode.state.data), diff --git a/examples/editor/index.html b/examples/editor/index.html index 3ed14b14..9ea3c931 100644 --- a/examples/editor/index.html +++ b/examples/editor/index.html @@ -25,9 +25,7 @@ renderer.setEventCallback(run) var trust = require("../../render/trust") var Editor = { - oninit: function() { - this.data = "# Markdown Editor\n\nType on the left panel and see the result on the right panel" - }, + data: "# Markdown Editor\n\nType on the left panel and see the result on the right panel", view: function(vnode) { return [ m("textarea.editor-input", {oninput: function(e) {vnode.state.data = e.target.value}}, vnode.state.data), diff --git a/render/tests/test-component.js b/render/tests/test-component.js index 862d36d2..1b51d8e0 100644 --- a/render/tests/test-component.js +++ b/render/tests/test-component.js @@ -576,4 +576,22 @@ o.spec("component", function() { o(vnode.dom).notEquals(updated.dom) }) }) + o.spec("state", function() { + o("deep copies state", function() { + var called = 0 + var component = { + data: [{a: 1}], + oninit: init, + view: function() { + return "" + } + } + + render(root, [{tag: component}]) + + function init(vnode) { + o(vnode.state.data).deepEquals([{a: 1}]) + } + }) + }) })