COMMUNITY

Haxe-react- howto create externs for grid-styled

How would I have to create correct externs to use the npm module grid-styled with haxe-react
my try turns my whole content into an empty page as soon as I add something like this to my jsx:

  <Flex>
	<Box width={1/2} px={2}>
	  Half width
	</Box>
	<Box width={1/2} px={2}>
	  Half width
	</Box>
</Flex>

What do your externs look like?

Are there console errors?
How are you building the project? with or without Webpack?

PS: you should add tags to your posts because this is fairly specific

meanwhile I switched to using react-flexview since it looks more promising after some tests.
Now my project still renders but when I navigate to my component FlexUI:

package ui;

import react.ReactComponent;
import redux.react.IConnectedComponent;
import react.ReactMacro.jsx;
import router.RouteComponentProps;
import redux.Redux.Dispatch;
import model.DataList;
import react_flexview.FlexView;
import react_virtualized.*;
 
class FlexUI 
	extends ReactComponentOfProps<IProps>
	implements IConnectedComponent
{
	public function new(props:IProps)
	{
		super(props);
	}

	override public function render():ReactElement
	{
		trace('go');
		// passing computed state as props and `dispatch` function
		return jsx('
    <FlexView>
      <FlexView grow={1} >1</FlexView>
      <FlexView grow={2} >2</FlexView>
    </FlexView>			
		');
	}	
}

I get console errors:

VM3516 ui_FlexUI.js:33 go
VM3497 libs.js:2006 Uncaught (in promise) TypeError: Cannot read property ‘hx_proxy’ of undefined
at Object.React.createElement (VM3497 libs.js:2006)
at ui_FlexUI.render (VM3516 ui_FlexUI.js:34)
at VM3497 libs.js:15853
at measureLifeCyclePerf (VM3497 libs.js:15132)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (VM3497 libs.js:15852)
at ReactCompositeComponentWrapper._renderValidatedComponent (VM3497 libs.js:15879)
at ReactCompositeComponentWrapper.performInitialMount (VM3497 libs.js:15419)
at ReactCompositeComponentWrapper.mountComponent (VM3497 libs.js:15315)
at Object.mountComponent (VM3497 libs.js:21689)
at ReactCompositeComponentWrapper.performInitialMount (VM3497 libs.js:15428)

Below my extern attempt for react-flexview:

package react_flexview;

import haxe.extern.EitherType;
import react.React.ReactChildren;
import react.ReactComponent;

/**
 * ...
 * @author axel@cunity.me
 */

typedef IProps = 
{
	?children:ReactChildren,
	?basis: EitherType<String,Int>,
	?className: String,
	?style: Dynamic,
	?width: EitherType<String,Int>,
	?height: EitherType<String,Int>,
	?column: EitherType <Bool,String>,
	?grow: EitherType <Bool,String>,
	?shrink: EitherType <Bool,String>,
	?vAlignContent: String,
	?hAlignContent: String,
	?marginLeft: EitherType<String,Int>,
	?marginRight: EitherType<String,Int>,
	?marginTop: EitherType<String,Int>,
	?marginBottom: EitherType<String,Int>,
	?wrap: Bool
}
 
@:jsRequire("react-flexview", "FlexView")
@:native('FlexView')
@:keepSub
@:autoBuild(react.ReactMacro.buildComponent())
@:autoBuild(react.ReactTypeMacro.alterComponentSignatures())
#if (debug && react_render_warning)
@:autoBuild(react.ReactDebugMacro.buildComponent())
#end
extern
class FlexView extends  ReactComponentOfProps<IProps>
{ }

the project template and build steps are as in the haxe-react-redux example

src/libs:

// 
// npm dependencies library
//
(function(scope) {
	'use-strict';
	scope.__registry__ = Object.assign({}, scope.__registry__, {
		
		// list npm modules required in Haxe
		
		'react': require('react'),
		'react-dom': require('react-dom'),
		'react-router': require('react-router'),
		'react-virtualized': require('react-virtualized'),
		'redux': require('redux'),
		'react-flexview': require('react-flexview')
	});
	
	if (process.env.NODE_ENV !== 'production') {
		// enable hot-reload
		require('haxe-modular');
	}
	
})(typeof $hx_scope != "undefined" ? $hx_scope : $hx_scope = {});

npm run libs
npm run serve

Ok, that’s good details :slight_smile:
This error happens in the hot-reload proxy code, so I’d suspect a problem with either the npm or haxelib side’s versions of Haxe modular. Please make sure they are both at 0.7.0, then re-run npm run libs.

ok there must be something different - have been on 0.7.0 and hot reloading already worked for the other compononents however after updating to 0.7.1 I get:

02:14:32.611 Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead. warning.js:36

After click on the navbar link to load FlexUI ()
I get:

02:15:58.821 Warning: React.createElement: type is invalid – expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it’s defined in. Check the render method of FlexUI.
in FlexUI (created by Unknown)
in Unknown (created by RouterContext)
in div (created by NavBar)
in NavBar (created by Unknown)
in Unknown (created by RouterContext)
in RouterContext (created by Router)
in Router
in Provider 3 warning.js:36

The warning is expected, it has been added to recent React 15.x releases to help the transition to React 16.

type is invalid... got: undefined means your extern is incorrect.
I need to write a guide about creating the externs and using NPM components…

And indeed it’s quite wrong, it should be:

@:jsRequire("react-flexview", "default")
extern class FlexView extends ReactComponentOfProps<IProps> {}

In general the JS import to Haxe’s jsRequire translation should be:

import * as Something from "some-module"; // ES6
const Something = require('some-module'); // JS
@:jsRequire('some-module') // Haxe

import Something from 'some-module'; // ES6
const Something = require('some-module').default; // JS
@:jsRequire('some-module', 'default') // Haxe

import { Something } from 'some-module'; // ES6
const Something = require('some-module').Something; // JS
@:jsRequire('some-module', 'Something') // Haxe

Additionally, from the NPM module documentation, you’re supposed to include some CSS.

import 'react-flexview/lib/flexView.css'; // JS

There are 2 options:

  • add require('react-flexview/lib/flexView.css') in libs.js; but you’ll have to modify the Browserify command to include a CSS transform (https://github.com/cheton/browserify-css),
  • copy it from node_modules/react-flexview/lib/flexView.css.

eventually
@:jsRequire(“react-flexview”,“default”)

was the only way I found to get rid of the errors and render the styles with FlexView

Ah my bad, yes it’s default - updating my answer with the right informaiton.

1 Like