Coder Social home page Coder Social logo

haxe-react's People

Contributors

ahuglajbclajep avatar andyli avatar efimster avatar elsassph avatar francescoagati avatar gama11 avatar jasononeil avatar jozefchutka avatar kevinresol avatar klabz avatar mansfield92 avatar markknol avatar philippe-elsass-deltatre avatar piotjag avatar roaclark avatar tmhrbr avatar tomashubelbauer 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  avatar

haxe-react's Issues

Node with more than 15 children crash the jsx macro

Hi !

I've just identified a bug that were pretty sneaky: if you have a node in your jsx code with more that 15 children, the jsx macro will crash with the following error: haxe-react/src/lib/api/react/ReactMacro.hx:98: characters 15-54 : Too many arguments

Here is a sample render component function that can lead to this issue:

override function render() {

    return jsx('
        <div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
            </div>
    ');
}

I think that come from the definition of this method in api.react.React:

public static function createElement(type:Dynamic, ?attrs:Dynamic,
        ?child1:Dynamic, ?child2:Dynamic, ?child3:Dynamic, ?child4:Dynamic, ?child5:Dynamic,
        ?child6:Dynamic, ?child7:Dynamic, ?child8:Dynamic, ?child9:Dynamic, ?child10:Dynamic,
        ?child11:Dynamic, ?child12:Dynamic, ?child13:Dynamic, ?child14:Dynamic, ?child15:Dynamic):ReactComponent;

That could be changed to this:

public static function createElement(type:Dynamic, ?attrs:Dynamic,
        ?children:haxe.extern.Rest<Dynamic>):ReactComponent;

But with this, it still do not compile:

haxe-react/src/lib/api/react/ReactMacro.hx:98: characters 15-54 : api.react.ReactComponent should be Null<haxe.extern.Rest<Dynamic>>
haxe-react/src/lib/api/react/ReactMacro.hx:98: characters 15-54 : api.react.ReactComponentOf<Dynamic, Dynamic, Dynamic> should be Null<haxe.extern.Rest<Dynamic>>
haxe-react/src/lib/api/react/ReactMacro.hx:98: characters 15-54 : api.react.ReactComponentOf<Dynamic, Dynamic, Dynamic> should be haxe.extern.Rest<Dynamic>
haxe-react/src/lib/api/react/ReactMacro.hx:98: characters 15-54 : For optional function argument 'children'

Do you see anything that could be done to make it accept a limitless number of children ?

HTML character entity unescaping

jsx('<div>&amp; &times;</div>') generates React.createElement("div",null,"&amp; &amp;times;")
Actual jsx generates React.createElement("div",null,"& ×")

Using external jsx instead of inline one

I wanted to use external jsx for instead of inline, with compiletime macro:


class Main {
    public static function main() {
        AppRegistry.registerComponent('TestReactNative', function() return App);

    }
}
@:expose('App')
class App extends ReactComponent{
    function new(props) {

        super(props);

        state = {
            scene: 0
        }
    }


    override function render() {
        function goto(i) setState({scene: i});
        return switch state.scene {
            default:
                jsx(CompileTime.readFile("jsx/Home.jsx"));
        }
    }
}

Home.jsx:

<WebView
    source={{uri: 'https://github.com/facebook/react-native'}}
    style={{marginTop: 20}}
>

</WebView>

but I got this error when compile:

/usr/local/lib/haxe/std/haxe/macro/ExprTools.hx:289: characters 11-16 : Unsupported expression: { expr => ECall({ expr => EField({ expr => EConst(CIdent(CompileTime)), pos => #pos(src/Main.hx:35: characters 20-31) },interpolateFile), pos => #pos(src/Main.hx:35: characters 20-47) },[{ expr => EConst(CString(jsx/Home.jsx)), pos => #pos(src/Main.hx:35: characters 48-62) }]), pos => #pos(src/Main.hx:35: characters 20-63) }
/Volumes/Work/develop/hx/libs/react/git/src/lib/react/ReactMacro.hx:27: characters 19-43 : Called from
src/Main.hx:35: characters 16-64 : Called from

How can I use external jsx with RNhaxe, if I can?

thanks

Better integration of HOC factories

Using more and more react js libraries like react-redux, react-intl, ... I face more and more the concept of Higher order component factories. This concept consist of wrapping your components to add it more features usually via props. It's done by exposing/exporting the result of a factory function that has been given your component class as parameters: for example here.

Another more complexe example is the ReactRedux.connect factory with can take more params.

While this is already implementable with haxe and haxe-react, I think we could had some metadata to expose directly the result of a HOC factory of component right in the same file as the component implementation itself. Something like:

typedef MyCompProps = {
    // (...)
}

@:hoc("myFactory" /*, other params ? */)
class MyComp extends ReactComponentOf<MyCompProps, Dynamic, Dynamic> {

    // (...)
}

We should also probably allow the @:hoc metada to be added several times on the same Component class...

In ES6, it seems we already have such a metadata feature for HOC factories: here is a es6 version use of the ReactRedux.connect factory.

And with javascript, we can (and usually do so) export the "factored" component in the same class file as the component class itself.

jsx syntax for inline if-else operator

I'm looking at some different styles of JSX syntax and haven't been able to adapt haxe-react's JSX to support this conditional syntax.

Is this a supported syntax? I suspect that the JSX macro parser has limits that I'm running into?

This simple structure works, the expression results in either 'online' or 'offline' returned as a string

${ AuthenticationService.isLoggedIn() ? ('online') : ('offline')}

But am unable to return conditional elements - the entire expression is treated as string

${ AuthenticationService.isLoggedIn() ? (<span>online<span/>) : (<span>offline<span/>)}

Here's the relevant JSX syntax I'm working to implement

https://facebook.github.io/react/docs/conditional-rendering.html#inline-if-else-with-conditional-operator

<div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>

JSX macro ignores any other elements after the first

return jsx('<h2>Messages</h2><ul>$messages</ul>');

This is not valid React code, because React currently doesn't support returning multiple elements from the render method: facebook/react#2127

I think the macro should issue a warning where there is an attempt to return multiple elements. It could point the developer in the direction of wrapping the elements into a wrapper div or something like that.

I am not sure I can provide a PR for this until I learn a little more Haxe so I'm just letting it be known for now.

Externs for common React addons / libs

This is just to let you know that I've started a github repo with externs for common React addons and libs there: https://github.com/tokomlabs/haxe-react-addons

This is definitively Work In Progress and many of them are just a @jsrequire call to the right lib path.

Bu if you have externs to share or if you'd like to start from there and add contributions, you are all very welcome.

I post this because of the TODO that is in the README of this repo:

TODO Externs for common. add-ons and react-router.

Why not just `react` package name?

I was wondering why the package name is api.react and not just react? It seems to me that the api intermediate package is not providing anything useful except noise in the code. At best I would just use the package name react (just like here or there) and at worst use react.api instead of api.react to have at least everything grouped into a common react package. I guess that your use of the api namespace might be related to the way you organize your packages internally, but I believe it would be best kept simple and as internal-naming-convention-agnostic as possible, especially for a library as popular as React!

Anyway, that's a lot of text for a rather minor issue ;)

It's good to see some activity around Haxe for the React library (and looking forward to see the updated jsx parser 👍 ).

Doesn't catch unclosed tags

jsx('
	<div>
		<p>Paragraph</p>
	<div/>
');

The above code is unclosed, but parsed as if it is closed with an extra </div>
This cause some hard-to-notice bug when there are some typos (just as in the case above it should be </div> instead of <div/>)

JSX syntax highlighting

FYI, I have been experimenting JSX syntax highlighting inside Haxe code in Atom (see screenshot below). It both works with jsx('<something>') (ie. haxe-react) and @jsx '<something>' constructs.

For now, the code is on a language-haxe fork (where I am working on improving the grammar in general, even though it is at exploration stage for now): https://github.com/jeremyfa/language-haxe

I thought some people around there might be interested about this.

capture d ecran 2016-03-20 a 23 51 18

Type the context

Hi !

It's really great to have the props, state and refs typed: ReactComponentOf<Dynamic, TState, TRefs>;.

Maybe we could type the context too ? With something like this: ReactComponentOf<Dynamic, TState, TRefs, TContext>;?

In api.react.ReactComponentOf it would look like this:

// (...)

extern class ReactComponentOf<TProps, TState, TRefs, TContext>
{
    static var defaultProps:Dynamic;
    static var contextTypes:Dynamic;

    var props(default, null):TProps;
    var state(default, null):TState;
    var context(default, null):TContext;
(...)

Regarding limitations

Hi,

First, great work with the lib. I'm getting into React and adding Haxe to the mix was something that was in the back of my head for some time, thanks for buidling and sharing this lib!

I'm curious about the following limitation:

You can't use functions (and thus factories) for stateless rendering. We're looking into this.

Do you mind providing a code example in the README depicting it? Also a short text explaining why it isn't possible with Haxe (and any possible workarounds) would be nice.

Thanks!

Thanks!

Using external lib won't compile anymore

I've just updated my haxe-react (I was still using a version from April) and now, because of this:

typedef CreateElementType = haxe.extern.EitherType<haxe.extern.EitherType<String, haxe.Constraints.Function>, Class<ReactComponent>>;

I cannot use extern classes like this for example:

@:jsRequire('react-redux', 'Provider')
extern class Provider { }

// ...

return jsx('
  <Provider store={store}>
    <Application />
  </Provider>
');

It seems the JSX macro now enforces elements to be either Strings, functions or classes extended ReactComponent...

Is there any solution to declare an extern class as extending ReactComponent ? Or should I write wrapping Haxe React component for every external component I want to use?

haxe-react-mmvc-master => empty page on apache

Hi,
this is the content chrome dev tools see on the url http://localhost/devel/bin/ after copying the whole bin tree into the apache document root - no errors on the console:

<title>React Mmvc</title> <script> if (!Object.assign || typeof Promise === 'undefined') { document.write('<script src="//cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/core.min.js">'); document.write('<script src="//cdnjs.cloudflare.com/ajax/libs/dom4/1.8.3/dom4.js">'); } </script> <script src="libs.js"></script> <script src="index.js"></script>

[literals] generated JS contains api.react.React or api.react.ReactComponentOf

Obviously they are incorrect because haxe classes with packages like that should be generated as api_react_React or api_react_ReactComponentOf.

I guess there are somewhere in the code that wrote untyped api.react.React so the compiler just generated them as-is.

I see this problem after the object-literal branch being merged.

Use haxe-react when react installed as a package

I'm struggling with using React addons components with haxe-react.

The problem is that most react addons are distributed as npm packages. They usually contains var React = require('react') statements which makes browserify including react in the output file (I did not find a way to exclude it from the output file).

On the other side, haxe-react seems to work only when React is used not as an npm package, but rather included via a script tag in the html page header.

The problem with this is that there can be only one React included at a time. If not, we get the following error at runtime:

Uncaught Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).

If then I remove the script tags that import react and react-dom, I get of course this, as my compile haxe-react code does not find React:

Uncaught ReferenceError: React is not defined

As it seems that react components are distributed as npm packages only, the way would be to make haxe-react work with an npm version of React. How can we do that ?

problem with regular expressions inside macros

This,
isn't a real bug of haxe-react but a bug of some distributions of haxe. Some cases of regular expression in haxe aren't supported.
In my case i have found this compiler error on my computer

Main.hx:11: lines 11-19 : Invalid JSX: Unsupported escaped char '{'

Rename ReactComponent to Component

and ReactPropTypes to PropTypes (and others...)

That is more consistent with the original library and makes copy-pasting from JS easier.

We can typedef ReactCompoent = react.Component to provide backward compatibility.

jsx macro not performing string interpolation for attributes ?

This is the render method of a component:

    override function render() {

        var sv = "some value";

        return jsx('
            <div className="page ${sv}">
                ${sv}
            </div>
        ');
    }

gives:

<div class="page {sv}" data-reactid=".0.$0">
  <span data-reactid=".0.$0.0">some value</span>
</div>

haxe-react and requiring addons

React addons seem to be available only as packages so far...

I'm trying to use the ReactCSSTransitionGroup addon.

What I've done so far is defining a haxe extern with the @:jsRequire metadata:

package api.react.addon;

@:jsRequire("react-addons-css-transition-group")
extern class ReactCSSTransitionGroup
{
    public static var transitionName : String;
    public static var transitionEnterTimeout : Int;
    public static var transitionLeaveTimeout : Int;
    // ...
}

In my app code, I use it like I would with any other React component:

    // ...
    override function render() {

        return jsx('
            <div className="app">
                <ReactCSSTransitionGroup transitionName="page" transitionEnterTimeout={500} transitionLeaveTimeout={300} >
                    {createPages()}
                </ReactCSSTransitionGroup>
            </div>
        ');
    }
    // ...

That doesn't work. It crashes at runtime with the following error:

Uncaught ReferenceError: require is not defined
console.undefined.log @ Type.hx:197
(anonymous function) @ ReactMacro.hx:121

We shouldn't define getInitialState() ?

I'm getting this warning at runtime if I define a getInitialState method in my React components:

Warning: getInitialState was defined on AppView, a plain JavaScript class. This is only supported for classes created using React.createClass. Did you mean to define a state property instead?

So I guess we should set this.state right in the constructor ?

That may be useful to document briefly all the deltas with using Rect with and without Haxe...

Invalid JSX

Just getting starting with react and haxe, but I'm hitting a jsx compilation issue I can't seem to fix no matter how I rearrange and tweak the jsx.

I've labeled line 82 that the compiler complains about:

return jsx('

			<InfiniteLoader
				isRowLoaded={isRowLoaded}
				loadMoreRows={loadMoreRows}
				rowCount={rowCount}
			>
				{({ onRowsRendered, registerChild }) => (
					<List
82:						ref={registerChild}
						onRowsRendered={onRowsRendered}
						rowRenderer={rowRenderer}
						{...otherProps}
					/>
				)}
			</InfiniteLoader>
		');

Gives this error:
src/example/todo/view/GalleryView.hx:82: lines 82-99 : Invalid JSX: Expected "

Any ideas?

context argument in component constructor and other component methods...

It seems that in the latest react version, the React.Component constructor and other React.Component methods like componentWillReceiveProps can take a context argument as parameter. Example here: https://github.com/reactjs/react-router/blob/c41309b3cd5ef5bf7e4b6e5219f0aba110557c7a/examples/animations/app.js#L22-L62

Right now this is now possible with haxe react... Is it just a matter or extending externs or is it more than that ?

support for load external file

Hi,
i'am try to use compiletime lib for load external file. But there is a macro conflict i think.

with this code
return jsx( CompileTime.interpolateFile('a.txt'));
i get
C:\HaxeToolkit\haxe\std/haxe/macro/ExprTools.hx:286: characters 11-16 : Unsupported expression: { expr => ECall({ expr => EField({ expr => EConst(CIdent(CompileTime)), pos => #pos(src/Main.hx:60: characters 20-31) },interpolateFile), pos => #pos(src/Main.hx:60: characters 20-47) },[{ expr => EConst(CString(a.txt)), pos => #pos(src/Main.hx:60: characters 48-55) }]), pos => #pos(src/Main.hx:60: characters 20-56) }

setState typing problem

The parameters provided to setState must contain all the fields defined in TState. Is it possible to override the type (or create another type) with macro to make all fields optional (for the setState function parameter only)?

Two workarounds for now:

  1. use untyped (e.g. setState(untyped {key:value});), but this defeats the purpose of using haxe's type system
  2. manually define all state fields as optional, but this is also not perfect

Can't use attribute without value in jsx

jsx('<button disabled>foo</button>');

This gives me Invalid JSX: Expected =, when react itself can handle jsx like that. Easy to work around, but confusing at first.

HTML text trimmed

var b = jsx('<em>bbb</em>');
var a = jsx('<div><span>a</span> / {b}</div>'

Results in React.createElement("div",null,React.createElement("span",null,"a"),"/ ",b);

In actual jsx it's React.createElement("div",null,React.createElement("span",null,"a")," / ",b);

Notice lack of first space in "/ "

Can't wrap existing react component with externs

When using existing react components, setDisplayName is trying to generate field for extern class.

extern class ExternComponent extends ReactComponent {}

This gives me Extern non-inline variables may not be initialized

Can be avoided by if (inClass.isExtern) return null; in setDisplayName

Unsupported escaped char '{'

I've just updated to libneko2 from PPA and now I get this error on any PCData element in jsx.
It come from ~/([^{]+|\{[^}]+\})/g regexp in ReactMacro.parseJsxNode
Works nice in ~/([^{]+|{[^}]+})/g form (notice lack of backslashes), but I don't know if this is proper PCRE and/or compatible with all Haxe platforms.

Is it possible to use dynamic content with this?

So I've been using this for a little while and gotten 1 or 2 apps working with it. But I've come to a situation - I want to use emoji in my current project and have to parse the content (which works fine). The library for emoji is a react-native one but I believe this is an issue? with jsx() rather than native export.

	private function parseEmoji(content:String):Dynamic {
		var match:EReg = ~/:([a-z0-9_]+):/g;
		if (content != null) {
			content = match.replace(content, '<Emoji name="$1" />');		
		}
		return content;
	}

So that would give me something like :coffee: test emoji to <Emoji name="coffee" /> which then becomes valid jsx syntax. When returning the code I then do

var emojify = this.parseEmoji(":coffee: test emoji");
var content = jsx('<Text style={styles.content}>$emojify</Text>');

but instead of parsing the $emojify as jsx code, it would print it literally as the replacement
(<Emoji name="coffee" /> test emoji). Is there a way around this?

jsx macro can generate also object literals

hi,
reading this article https://reactjsnews.com/how-to-make-your-react-apps-10x-faster i have see that react can process object literals for template.
This have some performance,beacuse instead of calling createElement we can simple return the object literal created from createElement at compile time when the macro jsx works.

we could add a flag like -D react-fast-jsx to make retrun object literals from jsx macro instead of React.createElement

Also babel has introduce this new features
`
Babel 5.8.24 introduces Inlining React elements: The optimisation.react.inlineElements transform converts JSX elements to object literals like {type: 'div', props: ...} instead of calls to React.createElement . This should only be enabled in production, since it disables some development warnings/checks.
•Babel 5.8.24 introduces Constant hoisting for React elements: The optimisation.react.constantElements transform hoists element creation to the top level for subtrees that are fully static, which reduces calls to React.createElement and the resulting allocations. More importantly, it tells React that the subtree hasn’t changed so React can completely skip it when reconciling. This should only be enabled in production, since it disables some development warnings/checks.

`

Jsx issue with custom component named "Loading"

I named one of my component Loading. In some of my other components where I'm using it, the haxe compilation sometimes generates things like this:

React.createElement("loading",null)

Instead of :

React.createElement(my_package_Loading,null)

The odd thing is that it does not generate this everywhere I use it.

CSS imports possible?

Is there a way to import css then use it?

E.g. one example I'm working with does this:

import styles from './InfiniteLoader.example.css'

Then refers to the CSS later on in JSX:

className={styles.List}

Is this possible (or even desirable) in haxe-react?

untyped causing problems

Follow up to #49

Case 1: typo not detected

jsx('<div onClick={function() tracee(0)}></div>');
// doesn't catch typo. output `tracee(0)` as is

Case 2: types not referenced

// data/Data.hx
enum Data {
    Video;
    Photo;
}

// Main.hx
import data.Data;
return jsx('<div onClick={function() return Media}></div>');
// output `return Media` as is, but should be something like `return data_Data.Media`

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.