Git Product home page Git Product logo

hyper-react's Introduction

The Complete Isomorphic Ruby Framework


Build Status Gem Version

Hyper-components

Hyper-React GEM is part of Hyperloop GEMS family

Hyper-react GEM comes with the Hyperloop GEM.

But if you want to install it separately, please install the Hyper-component GEM.

Community

Getting Help

Please do not post usage questions to GitHub Issues. For these types of questions use our Gitter chatroom or StackOverflow.

Submitting Bugs and Enhancements

GitHub Issues is for suggesting enhancements and reporting bugs. Before submiting a bug make sure you do the following:

License

Hyperloop is released under the MIT License.

hyper-react's People

Contributors

adamcreekroad avatar ajjahn avatar barriehadfield avatar catmando avatar donnadieu avatar fkchang avatar fzingg avatar gitter-badger avatar janbiedermann avatar jgaskins avatar johansmitsnl avatar josephgrossberg avatar kwhittington avatar maxdignan avatar noma4i avatar wied03 avatar zetachang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hyper-react's Issues

Warning on setting props.onEventName of React component

From @zetachang on April 12, 2015 8:37

Warning: Don't set .props.onClick of the React component <input />. Instead, specify the correct value when initially creating the element. The element was created by TodoItem.

Reason

If you are on React.js v0.13, you might see this warning, since upon 0.13, props will be immutable.

Solution

To make the syntax on(:event_name) still work. We will shift to React.cloneElement (https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement).

Copied from original issue: zetachang/react.rb#18

Need a way to deal with objects changing state (i.e. arrays)

From @catmando on May 3, 2015 4:5

For example

define_state(:foo) { ['joe', 'fred'] }

def add_friend(friend) 
  foo << friend
end

This does not work as foo << friend updates the array object, but there is no way to know that the foo state has been updated.

I have implemented a couple of solutions, and am interested in which people would prefer:

  1. define foo! method that will return an object that wrap the current value of foo, and observe any changes to that object. So you can write
def add_friend(friend)
  foo! << friend
end
  1. define foo! method that simple does foo = foo to indicate a state change. This would return self so that the methods could be chained
def add_friend(friend)
  foo << friend; foo!
end

or

def add_friend(friend)
  foo << friend
ensure
  foo!.bar!
end

2b) In addition the Proc class can be updated so this works

lambda { |new_friend| foo << new_friend }.foo! 

Just looking for people's input, preferences, or other ideas!

Copied from original issue: zetachang/react.rb#24

Upgrade Opal and other dependencies

From @jgaskins on March 4, 2015 4:6

Opal 0.7 was released a couple weeks ago, so I upgraded it and a few other dependencies here. This gives better support for source maps — and will allow it to be used with my latest projects based on Opal. ;-)

The only actual code changes I made were due to path-relative require statements no longer being valid. I just rewrote them to use canonical paths. Specs are still green, so that's a good sign. :-)

Copied from original issue: zetachang/react.rb/pull/10

how to get react.js source included?

From @catmando on May 6, 2015 22:3

I am working with the 0.8 opal branch
it does not include react-source (except in development)

The only way I can see to get react.js loaded is to include it in the index.html file?

Am I missing something?

Over on the opal gitter.im board, they figured you had a plan :-)

Copied from original issue: zetachang/react.rb#26

Cannot read property ‘firstChild’ of undefined

From @catmando on May 9, 2015 21:50

I am getting this error.

The web says this is caused by having 2 different versions of React.

I have tried every way to make sure that I only have one version, and I am still getting this error.

It is happening on the second render to a component, IF I am using opal-rspec in the browser.

I do not believe this is happening unless I am running opal-rspec.

I have done some basics like putting a console.log statement at the start of the react.js (unminimized) file and according to that log react.js is only loading once.

I have also made sure that react-source is not in my gem file.

Any clues or things to try would be greatly appreciated.

Copied from original issue: zetachang/react.rb#27

isomorphic execution

From @catmando on May 24, 2015 21:21

Does this work?

There are two strategies I think:

  1. run opal on the server

  2. make a server version of react.rb that calls through to JS

  3. would be faster but more maintenance

Copied from original issue: zetachang/react.rb#38

React v0.13 and Opal 0.8

From @wied03 on May 14, 2015 0:38

This is not meant to be a final pull request (just a discussion kickoff).

The main fixes I made here are:

  • Adapt to native_alias changes
  • Made tests that alter console.log a bit more robust
  • Build on ext/string work that someone else already noted

I had to try and fix an issue in Opal itself and that pull request is pending. In order to use my draft/fixed code, this project is currently pointing at my forks of opal and opal-rspec.

Anyways, hopefully this helps with talking about migration approaches, etc.

Copied from original issue: zetachang/react.rb/pull/31

JSX equivalent?

From @drewda on February 26, 2015 17:39

Any plans for including a markup DSL like JSX?

To give this a Ruby flavor, maybe let users embed Haml or Slim markup?

Copied from original issue: zetachang/react.rb#8

JSX Support

From @zetachang on March 8, 2015 9:19

Usage

Add .jsx to file which have JSX fragment.

class Fancy
  def render
    React.create_element('div') { "fancy" }
  end
end

class App
  include React::Component

  def render
    jsx(%x{
      <div>
        <h1>Outer</h1>
        <Fancy>{ #{5.times.to_a.join(",")} }</Fancy>
      </div>
    })
  end
end

React.expose_native_class(Fancy)

React.render React.create_element(App), `document.body`

JSX Transformer

Sprockets ES6 is added as dependency to transform .jsx file to vanilla JavaScript (only React transformer is used)

React.expose_native_class

Since JSX needs a reference to component class in global scope, this helper method is added.

Copied from original issue: zetachang/react.rb/pull/11

change define_state

From @catmando on April 28, 2015 18:11

I propose changing define_state to work like this:

define_state do |v1, v2, v3|
  v1 = "initial value"
  v2 = "some other initial value"
  # v3 never gets initialized
end

You can also do

define_state do |v1 = "foo", v2 = "bar"| end

which is very nice too.

This is possible after ruby 1.9 because you can get the list of parameter names for the block.

This syntax will work only if there are NO define_state parameter... i.e. define_state(:x) will continue to work as it does today.

I will be happy to implement this and do a pull request, I just want some feedback that this will be acceptable.

Copied from original issue: zetachang/react.rb#21

Benefit to using React.createClass ?

From @wied03 on May 27, 2015 19:47

I admittedly don't have an in depth understanding of exactly how react.rb maps to the underlying JS code, but would there be benefit in "caching" a Ruby/Opal class that includes React::Component such that https://github.com/facebook/react/blob/v0.13.1/src/classic/class/ReactClass.js is used?

It looks like, from the React code, there are some items it gets out of the way that might be nice for performance if a given component is used in several places.

That said, that would not play well with the monkey patching "feature" of Ruby

Maybe just calling createClass the first time someone tries to use a class and then holding on to that (e.g. in top_level.rb/create_element)?

Copied from original issue: zetachang/react.rb#43

Collision with Opal-JQuery

From @wied03 on May 21, 2015 23:19

(discovered in pull request).

Another problem I'm seeing here is that react.rb ends up inadvertently defining a top level Element class (in addition to the React::Element class). This conflicts with opal-jquery and makes opal-jq pretty much unusable.

I added a test to try and verify this is fixed and I tried to format the js code in element.rb better. I'm not quite proficient enough in JS at the moment to understand what that code is doing, but it looks like you're cleverly trying to make the React Element objects that React itself produces inherit from this class. This just seems to be a side effect.

A simpler way (I think) to see this problem is to compile the following:

class User
  attr_accessor :joe
  def initialize
    @joe = 'howdy'
  end
end

module Mod
  class User < %x{
    (function() {
      var f = function() {};
      f.prototype = Object.getPrototypeOf(String);
      return f;
    })()
  }
    def other_method
      'nope'
    end
  end
end

puts User.new.joe

Copied from original issue: zetachang/react.rb#36

Remove JSX support

From @zetachang on June 10, 2015 3:39

After discussing with @catmando, to support JSX, extra dependency on sprockets make it hard to maintain backward compatibility either for opal 0.7 or rails 3.

And given that the integration with react-rails gem is possible, we could simply rely on JSX compiling feature provided by it rather than rolling our own.

Copied from original issue: zetachang/react.rb#46

API Wrapping Coverage

From @zetachang on February 18, 2015 16:41

React

  • React.createClass - not valid, React.create_element automatically cache the component class
  • React.createElement
  • React.createFactory
  • React.render
  • React.unmountComponentAtNode
  • React.renderToString
  • React.renderToStaticMarkup
  • React.isValidElement
  • React.DOM - use DOM builder DSL instead
  • React.PropTypes - refer to #4
  • React.initializeTouchEvents

React.Children (simply make children include Enumerable)

  • React.Children.map - map
  • React.Children.forEach - each
  • React.Children.count - length, size
  • React.Children.only - only (throw what??)

ReactComponent

  • setState - set_state(next_state)
  • replaceState set_state!(next_state)
  • forceUpdate force_update!
  • getDOMNode dom_node (maybe return opal-browser's Node)
  • isMounted
  • setProps set_props
  • replaceProps set_props!(next_props)

Component Spec

  • render
  • getInitialState - provided from define_state yielded result
  • getDefaultProps - refer to #4
  • propTypes - refer to #4
  • mixins
  • statics: use ruby class method
  • displayName

Component Lifecycle

  • componentWillMount - before_mount helpers
  • componentDidMount - after_mount helpers
  • componentWillReceiveProps - before_receive_props(next_props)
  • shouldComponentUpdate - needs_update?(next_props, next_state)
  • componentWillUpdate - before_update(next_props, next_state)
  • componentDidUpdate - after_update(prev_props, prev_state)
  • componentWillUnmount - before_unmount
  • componentDidCatch - after_error(error, info)

Copied from original issue: zetachang/react.rb#2
meanwhile updated, more or less

[WIP] React v0.13

From @zetachang on April 1, 2015 12:49

Tracking progress of upgrading to React v0.13

  • Integrate master's React::Element work
  • React::Testing added to clean up testing code
  • native_alias all the life cycle methods
  • Make react-source as runtime dependency
  • Fix all the test warning
  • Separate code run in Ruby in opal namespace
  • Clarify the dependency with React.js (only depends on core rather than add ons)
  • update README
  • drop sprockets 2.0 (as opal master is dropping it)
  • ReactComponent access from this.refs is not ruby object
  • update examples
  • present(Foo).on(:event_name) won't work
  • raise error when deprecated method invoked
  • Object.assign shim

Copied from original issue: zetachang/react.rb/pull/17

error if component is not required

From @catmando on May 12, 2015 15:14

Say you do this:

React.render(React.create_element(MyFatComponent), Element['div.navigation'])

and you forget to require 'my_fat_component' Nothing happens, and there are no errors or warnings.

Instead the create_element binding (and similar) should make sure the constant does exist and responds to render.

Copied from original issue: zetachang/react.rb#30

how to render children in dsl?

From @catmando on May 21, 2015 17:39

Its not clear (or perhaps there is no way) to render children in the DSL.

For example

class ReverseDiv
  render
    div do
      params[:children].reverse.each do |child|
        # what do I do here? 
      end
   end
end

_Copied from original issue: zetachang/react.rb#35_

render should not fail silently

From @catmando on May 21, 2015 0:17

It would be a big help with debug if render would not fail silently, but instead simply print the exception raised etc.

Perhaps this is some setting in reactjs? Otherwise I am thinking that we could add a method render_debug to the component class, which calls render and prints any error message.

render_debug would be called by the API if it was available AND some kind of config switch was set.

Copied from original issue: zetachang/react.rb#34

with on(:click) react event can't access standard DOM methods

From @classyPimp on June 12, 2015 6:53

`
class Sample
include React::Component
define_state(:comments){
["foo", "bar"]
}

def handle_that(e)
p e.target.data('index') <----this not working
end

def render
div {
self.comments.each_with_index do |comment, index|
p("data-index" => index.to_s) { comment }.on(:click) { |e| handle_that(e) }
end
}
end
end
`

p e in handle_that returns Ract::Event object, p e.target returns Native paragraph object, but any other methods on p.target return "" or undefined, is it possible to access that target html, data attrs and so on? opal-browser and everything else is ok (using with rails).

Copied from original issue: zetachang/react.rb#50

How robust is this?

From @akshatpradhan on April 25, 2015 1:15

I'm curious how well can this integrate with the typical frameworks. For example, will this work inside apps that incorporate many frameworks (e.g animation.css, bootstrap.css, highcharts.js) inside their application.

Are there any examples of large enterprises using this in their rails app?

Let me know!

Copied from original issue: zetachang/react.rb#20

Upgrade to React v0.13

From @zetachang on April 12, 2015 9:31

React.js v0.13 is released last month (http://facebook.github.io/react/blog/2015/03/10/react-v0.13.html).
Some work need to be done in react.rb to catch up this release, there is zetachang/react.rb#17 which tracks all the changes introduced.

Depends on react-source

Previously , react-source gem v0.12.0 is only used as development dependency. Since the changes introduced will break in version under 0.13, so we will explicitly depends on react-source.

Also, you can now include the react source simply by adding a line as below without manually download or manage the source.

<%= javascript_include_tag 'react.js' %>

Toll-free bridge React::Component

We are introducing toll-free bridge React::Component.

Previously, the Ruby instance created through React.render(Foo) is actually not the component instance created by React.js framework. The Ruby instance is created during first mount and cached inside the actual component instance as a property.

Upgrading

All the DSL you got by include React::Component remains almost the same. Only difference is that previously the native ReactComponent will be passed as the first argument in the initializer of your class. But since the instance is actually the real ReactComponent instance. So simply refer to self in your initializer if you want to do stuff with it.

Other breaking changes

  • props are immutable now, so set_props & set_props! are deprecated, see official blog post for upgrading details.
  • set_state! are deprecated (since replaceState is deprecated , see original issue for more details)
  • dom_node is deprecated in favor of React.find_dom_node
  • React.find_dom_node return a plain DOM object rather than a Native

I will move all the details to wiki when this is actually done, and feel free to leave a comment if there is any concern or clarification needed. 😉

Copied from original issue: zetachang/react.rb#19

Opal 0.8 - WIP noise reducing syntax changes

From @catmando on May 14, 2015 22:18

This is WIP, just to see what you think of the changes.
For now its using my own copy of opal that better source mapping than the current version 0.7...

Summary of changes for discussion:

Any class with a render method can be used in the dsl by using the class name.

class MyComponent
  ...
end

class ParentComponent
  def render
    div do 
     MyComponent param1: 'foo' # works same as presents MyComponent ...
    end
  end
end

Component classes can also be scoped normally, so in the above example MyComponent could be a child, sibling, etc of ParentComponent. So if ParentComponents full name was Components::Admin::ParentComponent, then MyComponent could be a child of Components, Components::Admin, or Components::Admin::ParentComponent.

In the case where MyComponent was somewhere else in the module hierarchy the name can be qualified as needed. i.e. Shared::MyComponent

params can be specified as one a liner (similar to state, and rails attributes etc.)

required_param :foo   
optional_param :bar, default: "xyz"

params get their own read accessors just like state, so you can say

puts foo
puts bar

params with type Proc, can be called inside the component without using call.

required_param :inform_of_update, type: Proc
...
   inform_of_update "new text string"

state can now be updated by using the ! methods.

some_state!  12 # state now updated to 12, returns the previous value
some_state!   # without a param returns an object that will observe any changes to some_state
some_state! << 12 << 13 # assuming some_state is an array for example

the object returned by some_state! will also respond to :call, this allows
state to be easily passed as a Proc to a child param. For example

  my_component inform_of_update: my_state!   
  # compare to the equivalent
  present MyComponent, inform_of_update: -> (x) { self.my_state = x }

params can be of type React::Observable. Params of this type act like a Proc with an initial value. They can be read in the usual way, and can be update by calling the ! version. So they work like react linkages. State variables with the ! on the end are actually Observables, so you can now simply write:

  class MyInput

     required_param :value, type: React::Observable
     def render
       input(value: value).on(:change) { |new_value| value! new_value }
     end
   end

  class Parent
     define_state(:my_state) { "initial value"}
     def render
        MyInput value! # value will be updated by MyInput
     end
  end

If needed you can create an observable on the fly by calling watch(initial_value) { | updated_value | ... }

A copy of the current state is kept, so it can be read during events.
ReactJS does not guarantee the value of state being stable until after
the event completes.

So now its safe to write

   my_state! get_new_value
   my_state.each do { ... } #etc
# instead of
   temp = get_new_value
   temp.each do { ... } #etc

The React.render method can be passed a Opal Element directly (no need to do a get(0).

  React.render(element, Element['#todoapp'])
# works the same as
  React.render(element, Element['#todoapp'].get(0)) # this still works

There is a React::TopLevelComponent class. This provides several features:

  1. ability to create multiple react components mounted in various places on a single page and communicating. Very handy for evolving from other frameworks, as it allows subsections of the page to be redone as components.
  2. automatically mounts the components on DOM ready
  3. provides a safe mechanism to communicate from outside the React structure
class App < React::TopLevelComponent

  define_state :text do "I have never been clicked" end

  mount_component FriendsContainer, 'div#placeholder'
  mount_component JustSomeText, 'div#placeholder2' do {text: text} end

  external_update :update_text do |new_text| text! new_text end
end

elsewhere in old js code you can say

 $(document).ready(function() {
  var n = 0;
  $('#jquery-button').click(function() {    
    Opal.App.$update_text("I have been clicked "+n+"times")
  }}

Any calls to external updates will be queued until the top level component is mounted

The TopLevelComponent class can be defined across multiple files. This means it can be used to control the app layout across multiple pages, with each page adding its own "top level" behavior inside the page.

Well I think that's it... interested in what you think... I am using all these changes for my main company app, and should be deploying soon, so you can see it live in action.

I am happy to write the docs, update the samples, and of course write tests for all these.

Copied from original issue: zetachang/react.rb/pull/32

Exception handling

From @catmando on June 11, 2015 14:28

adds basic exception handler that handles exceptions during rendering and prints a meaningful error message. This has been an invaluable resource during our use of react.rb. Without this its much more difficult to track the source of the error.

Copied from original issue: zetachang/react.rb/pull/49

change name space

From @catmando on May 25, 2015 17:50

I keep running in to problems becuase react.rb is using the same name as react.js. Just crashed into this again trying to integrate with react-rails.

I suggest the file name be changed to opal-react (consistent with opal-jquery etc.) Module name can stay React.

I have tried this on my WIP branch, and it works great. After changing the file names to be opal-react, I was able to integrate without any difficulty with react-rails.

Please let me know your thoughts on this, and how to proceed re: pull request etc, as I want to go ahead and get this fully integrated with react-rails asap.

Copied from original issue: zetachang/react.rb#39

[discuss/random] DOM2React

From @elia on March 20, 2015 14:33

Did a quick experiment about creating react elements out of living DOM, here's the code:

https://gist.github.com/elia/fad23026831a817e3526

I'd like to hear opinions, not sure if this can be useful, but the initial idea was to render static dom and do progressive enhancement through react instead of jquery.

The other idea I'd like to bring to the table is haml2react.rb, kinda on the lines of the Glimmer engine that will come to next Ember version, that's probably a better idea :)

PS. sorry for opening an issue, not probably the best place for a discussion, but I though gitter would have been to sync, and I don't want to miss a single comment on this 🐸

Copied from original issue: zetachang/react.rb#13

Roadmap to release

From @zetachang on February 18, 2015 14:4

Copied from original issue: zetachang/react.rb#1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.