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

Releases: Roblox/roact

1.4.4

16 Aug 22:48
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.4.3...v1.4.4

v1.4.2

07 Oct 17:16
903bfe9
Compare
Choose a tag to compare

Removes the tempFixUpdateChildrenReEntrancy configuration flag and fixes an issue with context consumers

Changes since 1.4.1

  • Fixed forwardRef doc code referencing React instead of Roact (#310).
  • Fixed Listeners can only be disconnected once from context consumers. (#320)

v1.4.1

12 Aug 17:27
Compare
Choose a tag to compare

Patches behavior behind the tempFixUpdateChildrenReEntrancy config value to address additional reentrancy cases.

Changes since 1.4.0

  • Fixed a bug where the Roact tree could get into a broken state when using callbacks passed to a child component. Updated the tempFixUpdateChildrenReEntrancy config value to also handle this case. (#315)
  • Fixed forwardRef description (#312).

v1.4.0

03 Jun 19:03
fe67d5e
Compare
Choose a tag to compare

A number of small changes to error messaging and performance, as well as a forwardRef API that matches React.

Changes since 1.3.0

  • Introduce forwardRef (#307).
  • Fixed a bug where the Roact tree could get into a broken state when processing changes to child instances outside the standard lifecycle.
    • This change is behind the config value tempFixUpdateChildrenReEntrancy (#301)
  • Added color schemes for documentation based on user preference (#290).
  • Fixed stack trace level when throwing an error in createReconciler (#297).
  • Optimized the memory usage of 'createSignal' implementation. (#304)
  • Added component name to property validation error message (#275)

v1.3.0

11 May 20:25
58af06b
Compare
Choose a tag to compare

This release introduces the new Context API

Changes Since 1.2.0

v1.2.0

06 Sep 18:35
Compare
Choose a tag to compare

This release fixes a major bug with fragments and a minor behavioral inconsistency with setState.

Changes Since 1.1.0

  • Fixed an issue that prevented use of fragments within element children (#214)
  • Improved some error messages for invalid Roact.Change keys (#216)
  • Fix behavior inconsistency between assigning state in init and using setState (#232)

v1.1.0

03 Jun 22:00
Compare
Choose a tag to compare

This release fixes a minor reconciliation bug and introduces a new binding API, Roact.joinBindings.

Changes Since 1.0.0

  • Fixed an issue where updating a host element with children to an element with nil children caused the old children to not be unmounted. (#210)
  • Added Roact.joinBindings, which allows combining multiple bindings into a single binding that can be mapped. (#208)

Roact.joinBindings

The new joinBindings API can be used to combine multiple bindings and use them to create a new binding!

You can use this to implement flexible sizing without going through the reconciler, for example:

local function Flex()
	local aSize, setASize = Roact.createBinding(Vector2.new())
	local bSize, setBSize = Roact.createBinding(Vector2.new())

	return Roact.createElement("Frame", {
		Size = Roact.joinBindings({aSize, bSize}):map(function(sizes)
			local sum = Vector2.new()

			for _, size in ipairs(sizes) do
				sum = sum + size
			end

			return UDim2.new(0, sum.X,  0, sum.Y)
		end),
	}, {
		A = Roact.createElement("Frame", {
			Size = UDim2.new(1, 0, 0, 30),
			[Roact.Change.AbsoluteSize] = function(instance)
				setASize(instance.Size)
			end,
		}),
		B = Roact.createElement("Frame", {
			Size = UDim2.new(1, 0, 0, 30),
			Position = aSize:map(function(size)
				return UDim2.new(0, 0, 0, size.Y)
			end),
			[Roact.Change.AbsoluteSize] = function(instance)
				setBSize(instance.Size)
			end,
		}),
	})
end

v1.0.0

04 May 00:04
Compare
Choose a tag to compare

This release is the culmination of almost one year of work improving Roact's internals to pave the way for new features, optimizations, and ergonomic improvements.

We encourage existing projects to upgrade to 1.0.0 when possible. We feel that the improvements it brings over 0.2.0 and previous releases are substantial!

Changes Since 0.2.0

  • Added Fragments, which reduces the need for many container instances. (#172)
  • Added Bindings, which enables easy surgical updates to instances without using refs. (#159)
  • Added opt-in runtime type checking across the entire Roact API. (#188)
  • Added support for prop validation akin to React's propTypes.
  • Changed Component:setState to be deferred if it's called while Roact is updating a component. (#183)
  • Changed events connected via Roact.Event and Roact.Change triggered by a Roact update to be deferred until Roact is done updating the instance.
  • Improved and consolidated terminology across the board.
  • Improved errors to be much more informative and clear.

Fragments

The Roact.createFragment API enables returning multiple components from the render function of a function or stateful component.

Where we would previously have to create dummy Folder instances or nest elements endlessly, we can now return a fragment containing multiple objects!

Before, in 0.2.0:

local function Connectors()
    return Roact.createElement("Folder", {
        Keyboard = Roact.createElement(KeyboardConnector),
        Mouse = Roact.createElement(MouseConnector),
    })
end

Now, in 1.0.0:

local function Connectors()
    return Roact.createFragment({
        Keyboard = Roact.createElement(KeyboardConnector),
        Mouse = Roact.createElement(MouseConnector),
    })
end

Bindings

Bindings are a great way to build animations, as well as a good way to improve performance in cases where Roact isn't quite keeping up.

Check out our brand new bindings and refs guide for an introduction to how bindings can be used.

Bindings can be used to create an efficient, safe, and performant Roact fit-to-contents implementation:

local FitList = Roact.Component:extend("FitList")

function FitList:init()
    self.size, self.setSize = Roact.createBinding(Vector2.new())
end

function FitList:render()
    local children = {
        Layout = Roact.createElement("UIListLayout", {
            [Roact.Change.AbsoluteContentSize] = function(instance)
                self.setSize(instance.AbsoluteContentSize)
            end,
        })
    }

    for key, child in pairs(self.props[Roact.Children]) do
        children[key] = child
    end

    return Roact.createElement("Frame", {
        Size = self.size:map(function(absoluteSize)
            return UDim2.new(0, absoluteSize.X, 0, absoluteSize.Y)
        end),
    }, children)
end

Prop Validation

Set the validateProps value on your stateful component class to enable opting into strong type checking every time props update.

Prop validation is opt-in! To enable it in your project, use Roact.setGlobalConfig once somewhere in your project:

Roact.setGlobalConfig({
    propValidation = true,
})

When paired with libraries like t by Osyris, it's easy to make sure your components are accepting the correct props:

local CoolTextLabel = Roact.Component:extend("CoolTextLabel")

CoolTextLabel.validateProps = t.strictInterface({
    text = t.string,
    layoutOrder = t.optional(t.integer),
})

function CoolTextLabel:render()
    return Roact.createElement("TextLabel", {
        Size = UDim2.new(0, 400, 0, 400),
        Text = self.props.text,
        LayoutOrder = self.props.layoutOrder,
    })
end

Improved Terminology & Errors

We have a huge new suite of documentation and error messages that should make everything more clear when you run into problems.

v0.2.0

03 May 20:45
Compare
Choose a tag to compare

This is the first non-prerelease release of Roact, and the last one before we merge in a large refactor from our current development branch, new-reconciler.

We consider this release to be a stable release for existing projects using Roact prereleases.

Later today, we'll be publishing Roact 1.0, which includes almost a year of significant refactoring work and introduces a substantial number of features. We wanted to mark this release as the last version using the old Roact internals that have been proven stable in projects like the Roblox iOS, Android, and Xbox applications.

Changes since April 15th, 2019 Prerelease

  • Deprecated Roact.reconcile in favor of Roact.update (#194)
  • Removed some undocumented APIs:
    • Roact.getGlobalConfigValue, which let users read the current internal configuration.
    • Roact.Element, which let users figure out whether something is a Roact element. We'll introduce a proper type-checking API at a later date.

Prerelease 2019-04-15

15 Apr 18:42
Compare
Choose a tag to compare
Prerelease 2019-04-15 Pre-release
Pre-release

This prerelease is a roll-up of the changes since the latest prerelease, which was awhile ago!

Since the last prerelease, we've been working out of a new branch that we've been grooming to become Roact 1.0. It's on the new-reconciler branch if you're interested in checking it out, and it'll be merged to master within the next month or so hopefully!

Changes since last prerelease

  • setState can now be called inside init. Instead of triggering a new render, it will affect the currently scheduled one. (#139)
  • By default, disable the warning for an element changing types during reconciliation (#168)
  • Fixed a number of bugs with getDerivedStateFromProps