From ad0ae6afeb3f3d0056f16b4ff15d2dd7dbde8f7b Mon Sep 17 00:00:00 2001 From: Kampfkarren Date: Wed, 9 Oct 2019 12:45:01 -0700 Subject: [PATCH 1/3] Closes #199 --- src/Component.lua | 6 ++---- src/Component.spec/render.spec.lua | 15 +++++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Component.lua b/src/Component.lua index 5782af29..09adb93d 100644 --- a/src/Component.lua +++ b/src/Component.lua @@ -183,8 +183,6 @@ end Returns a snapshot of this component given the current props and state. Must be overridden by consumers of Roact and should be a pure function with regards to props and state. - - TODO (#199): Accept props and state as arguments. ]] function Component:render() local internalData = self[InternalData] @@ -287,7 +285,7 @@ function Component:__mount(reconciler, virtualNode) virtualNode.context = instance._context internalData.lifecyclePhase = ComponentLifecyclePhase.Render - local renderResult = instance:render() + local renderResult = instance:render(props, instance.state) internalData.lifecyclePhase = ComponentLifecyclePhase.ReconcileChildren reconciler.updateVirtualNodeWithRenderResult(virtualNode, hostParent, renderResult) @@ -450,7 +448,7 @@ function Component:__resolveUpdate(incomingProps, incomingState) self.props = incomingProps self.state = incomingState - local renderResult = virtualNode.instance:render() + local renderResult = virtualNode.instance:render(incomingProps, incomingState) internalData.lifecyclePhase = ComponentLifecyclePhase.ReconcileChildren reconciler.updateVirtualNodeWithRenderResult(virtualNode, virtualNode.hostParent, renderResult) diff --git a/src/Component.spec/render.spec.lua b/src/Component.spec/render.spec.lua index 8dac00a6..03aa1514 100644 --- a/src/Component.spec/render.spec.lua +++ b/src/Component.spec/render.spec.lua @@ -45,7 +45,7 @@ return function() expect(renderSpy.callCount).to.equal(1) - local renderArguments = renderSpy:captureValues("self") + local renderArguments = renderSpy:captureValues("self", "props", "state") expect(Type.of(renderArguments.self)).to.equal(Type.StatefulComponentInstance) assertDeepEqual(capturedProps, {}) @@ -57,7 +57,10 @@ return function() local capturedProps local capturedState - local renderSpy = createSpy(function(self) + local renderSpy = createSpy(function(self, props, state) + expect(props).to.equal(self.props) + expect(state).to.equal(self.state) + capturedProps = self.props capturedState = self.state end) @@ -74,7 +77,7 @@ return function() expect(renderSpy.callCount).to.equal(1) - local firstRenderArguments = renderSpy:captureValues("self") + local firstRenderArguments = renderSpy:captureValues("self", "props", "state") local firstProps = capturedProps local firstState = capturedState @@ -91,7 +94,7 @@ return function() expect(renderSpy.callCount).to.equal(2) - local secondRenderArguments = renderSpy:captureValues("self") + local secondRenderArguments = renderSpy:captureValues("self", "props", "state") local secondProps = capturedProps local secondState = capturedState @@ -127,7 +130,7 @@ return function() expect(renderSpy.callCount).to.equal(1) - local firstRenderArguments = renderSpy:captureValues("self") + local firstRenderArguments = renderSpy:captureValues("self", "props", "state") local firstProps = capturedProps local firstState = capturedState @@ -137,7 +140,7 @@ return function() expect(renderSpy.callCount).to.equal(2) - local renderArguments = renderSpy:captureValues("self") + local renderArguments = renderSpy:captureValues("self", "props", "state") expect(Type.of(renderArguments.self)).to.equal(Type.StatefulComponentInstance) expect(capturedProps).to.equal(firstProps) From f4ce5316be57bdb692f5c8bb800b23ec7ba8d0b3 Mon Sep 17 00:00:00 2001 From: Kampfkarren Date: Wed, 9 Oct 2019 12:46:53 -0700 Subject: [PATCH 2/3] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76191aaa..026a86cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Roact Changelog ## Unreleased Changes +* `render` now passes the incoming props and state ([#199](https://github.com/Roblox/roact/issues/199)) ## [1.2.0](https://github.com/Roblox/roact/releases/tag/v1.2.0) (September 6th, 2019) * Fixed a bug where derived state was lost when assigning directly to state in init ([#232](https://github.com/Roblox/roact/pull/232/)) From 9f8e31f410fe0fca81aa3fc934b00124aabc5411 Mon Sep 17 00:00:00 2001 From: Kampfkarren Date: Wed, 9 Oct 2019 12:50:26 -0700 Subject: [PATCH 3/3] Update documentation --- docs/api-reference.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/api-reference.md b/docs/api-reference.md index a51216ca..d449c357 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -400,20 +400,30 @@ end ### render ``` -render() -> Element | nil +render(props, state) -> Element | nil ``` `render` describes what a component should display at the current instant in time. +```lua +function MyComponent:render(props, state) + -- props == self.props + -- state == self.state + return Roact.createElement("TextLabel", { + Text = "Hello, " .. props.name .. "!" + }) +end +``` + !!! info Roact assumes that `render` act likes a pure function: the result of `render` must depend only on `props` and `state`, and it must not have side-effects. ```lua -function MyComponent:render() +function MyComponent:render(props, state) -- This is okay: return Roact.createElement("TextLabel", { - Text = self.props.text, - Position = self.state.position + Text = props.text, + Position = state.position }) -- Ack! Depending on values outside props/state is not allowed!