diff --git a/.rubocop.yml b/.rubocop.yml index f80bd1ff4..97697e0ff 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -44,13 +44,13 @@ Lint/HandleExceptions: - 'spec/dummy/bin/rake' Metrics/AbcSize: - Max: 25 + Max: 26 Metrics/CyclomaticComplexity: Max: 7 Metrics/PerceivedComplexity: - Max: 9 + Max: 10 Metrics/ClassLength: Max: 114 @@ -63,7 +63,7 @@ Metrics/MethodLength: Max: 41 Metrics/ModuleLength: - Max: 160 + Max: 180 Style/GlobalVars: Exclude: diff --git a/app/helpers/react_on_rails_helper.rb b/app/helpers/react_on_rails_helper.rb index 067c7cce8..ac2a14899 100644 --- a/app/helpers/react_on_rails_helper.rb +++ b/app/helpers/react_on_rails_helper.rb @@ -54,6 +54,8 @@ def react_component(component_name, options = {}, other_options = nil) # The reason is that React is smart about not doing extra work if the server rendering did its job. turbolinks_loaded = Object.const_defined?(:Turbolinks) + props = {} if props.nil? + data = { component_name: react_component_name, props: props, @@ -237,10 +239,13 @@ def replay_console(options) end def parse_options_props(component_name, options, other_options) - if options.is_a?(Hash) && options.key?(:props) # new syntax + other_options ||= {} + if options.is_a?(Hash) && options.key?(:props) props = options[:props] + final_options = options.except(:props) + final_options.merge!(other_options) if other_options.present? else - deprecated_syntax = false + # either no props specified or deprecated if other_options.present? || options.is_a?(String) deprecated_syntax = true else @@ -248,7 +253,7 @@ def parse_options_props(component_name, options, other_options) %i(prerender trace replay_console raise_on_prerender_error).none? do |key| options.key?(key) end - deprecated_syntax = true if options_has_no_reserved_keys + deprecated_syntax = options_has_no_reserved_keys end if deprecated_syntax @@ -257,9 +262,12 @@ def parse_options_props(component_name, options, other_options) "component_name: #{component_name}, controller: #{controller_name}, "\ "action: #{action_name}." props = options - options = other_options + final_options = other_options + else + options ||= {} + final_options = options.merge(other_options) end end - [options, props] + [final_options, props] end end diff --git a/spec/dummy/app/views/pages/client_side_hello_world_shared_store.html.erb b/spec/dummy/app/views/pages/client_side_hello_world_shared_store.html.erb index c0c8c1238..c35b37a77 100644 --- a/spec/dummy/app/views/pages/client_side_hello_world_shared_store.html.erb +++ b/spec/dummy/app/views/pages/client_side_hello_world_shared_store.html.erb @@ -1,13 +1,13 @@ <%= render "header" %> <%= redux_store("SharedReduxStore", @app_props_server_render) %> -<%= react_component("ReduxSharedStoreApp", props: {}, prerender: false, trace: true) %> +<%= react_component("ReduxSharedStoreApp", prerender: false, trace: true) %>
-

Second Hello World

-<%= react_component("ReduxSharedStoreApp", props: {}, prerender: false, trace: true) %> +

Second Hello World

+<%= react_component("ReduxSharedStoreApp", prerender: false, trace: true) %>
-

React Rails Client Side Only Rendering

+

React Rails Client Side Only Rendering, 2 components, same Redux store

This example demonstrates using 2 components attached to the same store.

@@ -16,22 +16,24 @@

Setup

  1. - Create component source: spec/dummy/client/app/components/HelloWorld.jsx + Create component source: spec/dummy/client/app/startup/ReduxSharedStoreApp.jsx
  2. - Expose the HelloWorld Component: spec/dummy/client/app/startup/clientRegistration.jsx -
    -
    -      import HelloWorld from '../components/HelloWorld';
    -      import ReactOnRails from 'react-on-rails';
    -      ReactOnRails.register({ HelloWorld });
    -    
    + Create store source: spec/dummy/client/app/stores/SharedReduxStore.jsx
  3. - Place the component on the view: spec/dummy/app/views/pages/client_side_hello_world.html.erb + Register the components: spec/dummy/client/app/startup/clientRegistration.jsx +
  4. +
  5. + Place the components and store on the view: spec/dummy/app/views/pages/client_side_hello_world_shared_store.html.erb
    -      <%%= react_component("HelloWorld", props: @app_props_server_render, prerender: false, trace: true) %>
    +<%%= redux_store("SharedReduxStore", @app_props_server_render) %>
    +
    +<%%= react_component("ReduxSharedStoreApp", prerender: false, trace: true) %>
    +
    +Second Hello World
    +<%%= react_component("ReduxSharedStoreApp", prerender: false, trace: true) %>
         
diff --git a/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb b/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb index 109bccb2e..80d90258f 100644 --- a/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb +++ b/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb @@ -36,7 +36,7 @@ end describe "#react_component" do - subject { react_component("App", props) } + subject { react_component("App", props: props) } let(:props) do { name: "My Test Name" } @@ -58,6 +58,13 @@ data-dom-id="#{id}">).squish end + describe "deprecated API" do + subject { react_component("App", props) } + it { is_expected.to be_an_instance_of ActiveSupport::SafeBuffer } + it { is_expected.to include react_component_div } + it { is_expected.to include react_definition_div } + end + it { expect(self).to respond_to :react_component } it { is_expected.to be_an_instance_of ActiveSupport::SafeBuffer }