Skip to content

Commit fd25322

Browse files
justin808claude
andcommitted
Refactor immediate_hydration logic into shared utility method
Address code review feedback: 1. Consolidate duplicated immediate_hydration logic - Create ReactOnRails::Utils.normalize_immediate_hydration method - Replace inline logic in controller, helper, and render_options - Reduces code duplication from 3 locations to 1 shared method 2. Document the == true check rationale - Added comprehensive YARD documentation - Explains strict equality is intentional (not truthy check) - Prevents false positives from strings like "yes"/"no" - Type safety handled at call site by Ruby's type system Benefits: - Single source of truth for immediate_hydration normalization - Easier to test and maintain - Clear documentation of behavior - Consistent warning messages across all entry points 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 2e54457 commit fd25322

File tree

4 files changed

+37
-27
lines changed

4 files changed

+37
-27
lines changed

lib/react_on_rails/controller.rb

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,7 @@ module Controller
1515
# Be sure to include view helper `redux_store_hydration_data` at the end of your layout or view
1616
# or else there will be no client side hydration of your stores.
1717
def redux_store(store_name, props: {}, immediate_hydration: nil)
18-
# If non-Pro user explicitly sets immediate_hydration: true, warn and override to false
19-
if immediate_hydration == true && !ReactOnRails::Utils.react_on_rails_pro?
20-
Rails.logger.warn ReactOnRails::Utils.immediate_hydration_pro_license_warning(store_name, "Store")
21-
immediate_hydration = false
22-
elsif immediate_hydration.nil?
23-
immediate_hydration = ReactOnRails::Utils.react_on_rails_pro?
24-
end
18+
immediate_hydration = ReactOnRails::Utils.normalize_immediate_hydration(immediate_hydration, store_name, "Store")
2519

2620
redux_store_data = { store_name: store_name,
2721
props: props,

lib/react_on_rails/helper.rb

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,7 @@ def react_component_hash(component_name, options = {})
158158
# immediate_hydration: nil -- React on Rails Pro (licensed) feature. When nil (default), Pro users
159159
# get immediate hydration, non-Pro users don't. Can be explicitly overridden.
160160
def redux_store(store_name, props: {}, defer: false, immediate_hydration: nil)
161-
# If non-Pro user explicitly sets immediate_hydration: true, warn and override to false
162-
if immediate_hydration == true && !ReactOnRails::Utils.react_on_rails_pro?
163-
Rails.logger.warn ReactOnRails::Utils.immediate_hydration_pro_license_warning(store_name, "Store")
164-
immediate_hydration = false
165-
elsif immediate_hydration.nil?
166-
immediate_hydration = ReactOnRails::Utils.react_on_rails_pro?
167-
end
161+
immediate_hydration = ReactOnRails::Utils.normalize_immediate_hydration(immediate_hydration, store_name, "Store")
168162

169163
redux_store_data = { store_name: store_name,
170164
props: props,

lib/react_on_rails/react_component/render_options.rb

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,11 @@ def logging_on_server
9696
end
9797

9898
def immediate_hydration
99-
explicit_value = options[:immediate_hydration]
100-
101-
# If non-Pro user explicitly sets immediate_hydration: true, warn and override to false
102-
if explicit_value == true && !ReactOnRails::Utils.react_on_rails_pro?
103-
warning = ReactOnRails::Utils.immediate_hydration_pro_license_warning(react_component_name, "Component")
104-
Rails.logger.warn warning
105-
return false # Force fallback to standard hydration
106-
end
107-
108-
# Return explicit value if provided, otherwise default based on Pro license
109-
return explicit_value unless explicit_value.nil?
110-
111-
ReactOnRails::Utils.react_on_rails_pro?
99+
ReactOnRails::Utils.normalize_immediate_hydration(
100+
options[:immediate_hydration],
101+
react_component_name,
102+
"Component"
103+
)
112104
end
113105

114106
def to_s

lib/react_on_rails/utils.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,36 @@ def self.immediate_hydration_pro_license_warning(name, type = "Component")
2020
"Visit https://www.shakacode.com/react-on-rails-pro/ for licensing information."
2121
end
2222

23+
# Normalizes the immediate_hydration option value, enforcing Pro license requirements.
24+
# Returns the normalized boolean value for immediate_hydration.
25+
#
26+
# @param value [Boolean, nil] The immediate_hydration option value
27+
# @param name [String] The name of the component/store (for warning messages)
28+
# @param type [String] The type ("Component" or "Store") for warning messages
29+
# @return [Boolean] The normalized immediate_hydration value
30+
#
31+
# Logic:
32+
# - If value is explicitly true (boolean) and no Pro license: warn and return false
33+
# - If value is nil: return true for Pro users, false for non-Pro users
34+
# - Otherwise: return the value as-is (allows explicit false to work)
35+
#
36+
# Note: We check for `== true` (not truthy) to only trigger on explicit boolean true,
37+
# not on strings like "yes" or other truthy values which should be rejected by Ruby's
38+
# type system at the call site.
39+
def self.normalize_immediate_hydration(value, name, type = "Component")
40+
# Strict equality check: only trigger warning for explicit boolean true
41+
if value == true && !react_on_rails_pro?
42+
Rails.logger.warn immediate_hydration_pro_license_warning(name, type)
43+
return false
44+
end
45+
46+
# If nil, default based on Pro license status
47+
return react_on_rails_pro? if value.nil?
48+
49+
# Return explicit value (including false)
50+
value
51+
end
52+
2353
# https://forum.shakacode.com/t/yak-of-the-week-ruby-2-4-pathname-empty-changed-to-look-at-file-size/901
2454
# return object if truthy, else return nil
2555
def self.truthy_presence(obj)

0 commit comments

Comments
 (0)