Skip to content
This repository has been archived by the owner on Dec 13, 2023. It is now read-only.

Commit

Permalink
Merge 9f8e31f into deaa800
Browse files Browse the repository at this point in the history
  • Loading branch information
Kampfkarren committed Oct 9, 2019
2 parents deaa800 + 9f8e31f commit bfdbb5e
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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/))
Expand Down
18 changes: 14 additions & 4 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Expand Down
6 changes: 2 additions & 4 deletions src/Component.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 9 additions & 6 deletions src/Component.spec/render.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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, {})
Expand All @@ -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)
Expand All @@ -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

Expand All @@ -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

Expand Down Expand Up @@ -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

Expand All @@ -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)
Expand Down

0 comments on commit bfdbb5e

Please sign in to comment.