Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions modules/react-debug-tools/src/ReactDebugHooks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,14 @@ local function getPrimitiveStackCache(): Map<string, Array<any>>
-- Dispatcher:useMemo(function()
Dispatcher.useDebugValue(nil)
Dispatcher.useCallback(function() end)
-- ROBLOX upstream: https://github.com/facebook/react/pull/28399
Dispatcher.useSyncExternalStore(function()
return function() end
end, function()
return nil
end, function()
return nil
end)
Dispatcher.useMemo(function()
-- ROBLOX deviation END
return nil
Expand Down Expand Up @@ -444,6 +452,24 @@ local function useMutableSource<Source, Snapshot>(
) --[[ ROBLOX CHECK: check if 'hookLog' is an Array ]]
return value
end
-- ROBLOX upstream: https://github.com/facebook/react/blob/34aa5cfe0d9b6ec4667e02bf46ab34d83dfb2d6d/packages/react-debug-tools/src/ReactDebugHooks.js#L276-L294
local function useSyncExternalStore<T>(
subscribe: (() -> ()) -> () -> (),
getSnapshot: () -> T,
getServerSnapshot: (() -> T)?
): T
-- useSyncExternalStore() composes multiple hooks internally.
-- Advance the current hook index the same number of times
-- so that subsequent hooks have the right memoized state.
nextHook() -- SyncExternalStore
nextHook() -- Effect
local value = getSnapshot()
table.insert(
hookLog,
{ primitive = "SyncExternalStore", stackError = Error.new(), value = value }
)
return value
end
-- ROBLOX deviation START: enable these once they are fully enabled in the Dispatcher type and in ReactFiberHooks' myriad dispatchers
-- local function useTransition(
-- ): any --[[ ROBLOX TODO: Unhandled node for type: TupleTypeAnnotation ]] --[[ [(() => void) => void, boolean] ]]
Expand Down Expand Up @@ -535,6 +561,7 @@ Dispatcher = {
-- useTransition = useTransition,
-- ROBLOX deviation END
useMutableSource = useMutableSource,
useSyncExternalStore = useSyncExternalStore,
-- ROBLOX deviation START: not implemented
-- useDeferredValue = useDeferredValue,
-- ROBLOX deviation END
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,40 @@ describe("ReactHooksInspectionIntegration", function()
},
})
end)
it("should support composite useSyncExternalStore hook", function()
local useSyncExternalStore = React.useSyncExternalStore
local function Foo()
local value = useSyncExternalStore(function()
return function() end
end, function()
return "snapshot"
end)
React.useMemo(function()
return "memo"
end, {})
return value
end

local renderer = ReactTestRenderer.create(React.createElement(Foo, nil))
local childFiber = renderer.root:findByType(Foo):_currentFiber()
local tree = ReactDebugTools.inspectHooksOfFiber(childFiber)
expect(tree).toEqual({
{
id = 1,
isStateEditable = false,
name = "SyncExternalStore",
value = "snapshot",
subHooks = {},
},
{
id = 2,
isStateEditable = false,
name = "Memo",
value = "memo",
subHooks = {},
},
})
end)
-- ROBLOX deviation START: no experimental features
-- if Boolean.toJSBoolean(__EXPERIMENTAL__) then
-- it("should support composite useMutableSource hook", function()
Expand Down
9 changes: 6 additions & 3 deletions modules/react-reconciler/src/ReactFiberFlags.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,17 @@ exports.Hydrating = --[[ ]]
0b000000010000000000
exports.HydratingAndUpdate = --[[ ]]
0b000000010000000100
-- ROBLOX deviation: appended to preserve the values of existing flags.
exports.StoreConsistency = --[[ ]]
0b1000000000000000000

-- Passive & Update & Callback & Ref & Snapshot
-- Passive & Update & Callback & Ref & Snapshot & StoreConsistency
exports.LifecycleEffectMask = --[[ ]]
0b000000001110100100
0b1000000001110100100

-- Union of all host effects
exports.HostEffectMask = --[[ ]]
0b000000011111111111
0b1000000011111111111

-- These are not really side effects, but we still reuse this field.
exports.Incomplete = --[[ ]]
Expand Down
Loading