Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Hypercomponent does not run on older browsers #220

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
catmando opened this issue Jul 23, 2019 · 1 comment
Closed

Hypercomponent does not run on older browsers #220

catmando opened this issue Jul 23, 2019 · 1 comment
Labels
bug Something isn't working

Comments

@catmando
Copy link
Contributor

This is due to hyper-component creating components using ECMA 6 classes, which are not supported by older browsers.

Instead rewrite to use createReactClass https://reactjs.org/docs/react-without-es6.html

@catmando catmando added the bug Something isn't working label Jul 23, 2019
@catmando
Copy link
Contributor Author

catmando commented Jul 25, 2019

Fixed on edge.

CAUTION if you are using webpacker you must add the create-react-class NPM module and require it in your client_and_server.js packs file:

  1. yarn add create-react-class
  2. in the app/javascript/packs/client_and_server.js file add this line:
    createReactClass = require('create-react-class');

If you want to patch this change instead of taking edge you can add the patch as follows:

module Hyperstack
  module Internal
    module Component
      class ReactWrapper
        def self.create_native_react_class(type)
          raise "createReactClass is undefined. Add the 'react-create-class' npm module, and import it as 'createReactClass'" if `typeof(createReactClass)=='undefined'`
          raise "Provided class should define `render` method"  if !(type.method_defined? :render)
          render_fn = (type.method_defined? :_render_wrapper) ? :_render_wrapper : :render
          # this was hashing type.to_s, not sure why but .to_s does not work as it Foo::Bar::View.to_s just returns "View"

          @@component_classes[type] ||= begin
            comp = %x{
              createReactClass({
                getInitialState: function() {
                  this.mixins = #{type.respond_to?(:native_mixins) ? type.native_mixins : `[]`};
                  this.statics = #{type.respond_to?(:static_call_backs) ? type.static_call_backs.to_n : `{}`};
                  this.__opalInstanceInitializedState = false;
                  this.__opalInstanceSyncSetState = true;
                  this.__opalInstance = #{type.new(`this`)};
                  this.__opalInstanceInitializedState = true;
                  this.__opalInstanceSyncSetState = false;
                  this.__name = #{type.name};
                  return {}
                },
                displayName: #{type.name},
                getDefaultProps: function() {
                  return #{type.respond_to?(:default_props) ? type.default_props.to_n : `{}`};
                },
                propTypes: #{type.respond_to?(:prop_types) ? type.prop_types.to_n : `{}`},
                componentWillMount: function() {
                  if (#{type.method_defined? :component_will_mount}) {
                    this.__opalInstanceSyncSetState = true;
                    this.__opalInstance.$component_will_mount();
                    this.__opalInstanceSyncSetState = false;
                  }
                },
                componentDidMount: function() {
                  this.__opalInstance.__hyperstack_component_is_mounted = true
                  if (#{type.method_defined? :component_did_mount}) {
                    this.__opalInstanceSyncSetState = false;
                    this.__opalInstance.$component_did_mount();
                  }
                },
                componentWillReceiveProps: function(next_props) {
                  if (#{type.method_defined? :component_will_receive_props}) {
                    this.__opalInstanceSyncSetState = true;
                    this.__opalInstance.$component_will_receive_props(Opal.Hash.$new(next_props));
                    this.__opalInstanceSyncSetState = false;
                  }
                },
                shouldComponentUpdate(next_props, next_state) {
                  if (#{type.method_defined? :should_component_update?}) {
                    this.__opalInstanceSyncSetState = false;
                    return this.__opalInstance["$should_component_update?"](Opal.Hash.$new(next_props), Opal.Hash.$new(next_state));
                  } else { return true; }
                },
                componentWillUpdate: function(next_props, next_state) {
                  if (#{type.method_defined? :component_will_update}) {
                    this.__opalInstanceSyncSetState = false;
                    this.__opalInstance.$component_will_update(Opal.Hash.$new(next_props), Opal.Hash.$new(next_state));
                  }
                },
                componentDidUpdate: function(prev_props, prev_state) {
                  if (#{type.method_defined? :component_did_update}) {
                    this.__opalInstanceSyncSetState = false;
                    this.__opalInstance.$component_did_update(Opal.Hash.$new(prev_props), Opal.Hash.$new(prev_state));
                  }
                },
                componentWillUnmount: function() {
                  if (#{type.method_defined? :component_will_unmount}) {
                    this.__opalInstanceSyncSetState = false;
                    this.__opalInstance.$component_will_unmount();
                  }
                  this.__opalInstance.__hyperstack_component_is_mounted = false;
                },
                render: function() {
                  this.__opalInstanceSyncSetState = false;
                  return this.__opalInstance.$send(render_fn).$to_n();
                }
              })
            }
            # check to see if there is an after_error callback.  If there is add a
            # componentDidCatch handler. Because legacy behavior is to allow any object
            # that responds to render to act as a component we have to make sure that
            # we have a callbacks_for method.  This all becomes much easier once issue
            # #270 is resolved.
            if type.respond_to?(:callbacks?) && type.callbacks?(:after_error)
              add_after_error_hook_to_native comp
            end
            comp
          end
        end
    end
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant