Skip to content

Commit

Permalink
FunctionComponent.Of prepared func cache key extended to include 'Pro…
Browse files Browse the repository at this point in the history
…ps type name
  • Loading branch information
Nick Dunets committed May 17, 2024
1 parent e217327 commit 2f39899
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 11 deletions.
19 changes: 12 additions & 7 deletions src/Fable.React/Fable.React.FunctionComponent.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ open Fable.Core
open Fable.Core.JsInterop

#if FABLE_COMPILER
type internal Cache() =
type FunctionComponentPreparedRenderFunctionCache() =
static let cache =
let cache = JS.Constructors.Map.Create<string, obj>()
#if DEBUG
// Clear the cache when HMR is fired
Cache.OnHMR(fun () -> cache.clear())
FunctionComponentPreparedRenderFunctionCache.OnHMR(fun () -> cache.clear())
#endif
cache

Expand Down Expand Up @@ -57,7 +57,7 @@ type FunctionComponent =
/// and is displayed in React dev tools (use `displayName` to customize the name).
/// Uses React.memo if `memoizeWith` is specified (check `equalsButFunctions` and `memoEqualsButFunctions` helpers).
/// When you need a key to optimize collections in React you can use `withKey` argument or define a `key` field in the props object.
static member Of(render: 'Props->ReactElement,
static member inline Of(render: 'Props->ReactElement,
?displayName: string,
?memoizeWith: 'Props -> 'Props -> bool,
?withKey: 'Props -> string
Expand All @@ -68,7 +68,7 @@ type FunctionComponent =
#endif
): 'Props -> ReactElement =
#if FABLE_COMPILER
let prepareRenderFunction _ =
let prepareRenderFunction (_: string) =
let displayName = defaultArg displayName __callingMemberName.Value
render?displayName <- displayName
let elemType =
Expand All @@ -77,7 +77,7 @@ type FunctionComponent =
#if DEBUG
// In development mode, force rerenders always when HMR is fired
let areEqual x y =
not Cache.IsHMRApplied && areEqual x y
not FunctionComponentPreparedRenderFunctionCache.IsHMRApplied && areEqual x y
#endif
let memoElement = ReactElementType.memoWith areEqual render
memoElement?displayName <- "Memo(" + displayName + ")"
Expand All @@ -92,8 +92,13 @@ type FunctionComponent =

// Cache the render function to prevent recreating the component every time when FunctionComponent.Of
// is called inside another function (including generic values: let MyCom<'T> = ...)
let cacheKey = __callingSourceFile.Value + "#L" + (string __callingSourceLine.Value)
Cache.GetOrAdd(cacheKey, prepareRenderFunction)
let cacheKey =
__callingSourceFile.Value +
"#L" + (string __callingSourceLine.Value) +
// direct caller can also be generic, need separate cached func per 'Props argument
";" + typeof<'Props>.FullName

FunctionComponentPreparedRenderFunctionCache.GetOrAdd(cacheKey, prepareRenderFunction)
#else
let elemType = ReactElementType.ofFunction render
fun props ->
Expand Down
7 changes: 3 additions & 4 deletions src/Fable.React/Fable.React.fsproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>9.3.0</Version>
<PackageVersion>9.3.0</PackageVersion>
<Version>9.4.0</Version>
<PackageVersion>9.4.0</PackageVersion>
<TargetFramework>netstandard2.0</TargetFramework>
<!-- <DefineConstants>$(DefineConstants);FABLE_COMPILER</DefineConstants> -->
<DefineConstants>$(DefineConstants);FABLE_COMPILER</DefineConstants>
<PackageTags>fsharp;fable;javascript;f#;js;react;fable-library;fable-javascript;fable-dotnet</PackageTags>
</PropertyGroup>
<ItemGroup>
Expand All @@ -24,6 +24,5 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Fable.React.Types\Fable.React.Types.fsproj" />
<ProjectReference Include="..\Fable.ReactDom.Types\Fable.ReactDom.Types.fsproj" />
</ItemGroup>
</Project>

0 comments on commit 2f39899

Please sign in to comment.