Fork me on GitHub
#rum
<
2017-05-09
>
grounded_sage02:05:40

What concepts Ali?

grounded_sage02:05:01

:autoplay true doesn't seem to work for me on client side. Renders serverside fine.

grounded_sage02:05:18

Also tried "autoplay" true

grounded_sage02:05:59

:auto-play "autoplay" or :auto-play true Fixes it. nvm 🙂

kurt-o-sys11:05:02

react-navigation: I'm using re-natal with rum and I want to implement a navigator (using react-navigation). 1. Get the stack-navigator:

(def ReactNavigation (js/require "react-navigation"))
(def stack-nav (.-StackNavigator ReactNavigation))
seems to be ok 2. Define the AppRoot (Home):
(defc AppRoot < rum/reactive pn/react-mixin
  [app markers]
  ...)
3. Implement the navigator... Well, without navigator, I have this line (support/mount (AppRoot state/app state/markers)). I will have to change this to mount the navigator. Implementing the navigator...
my.ns.android.core=> (def c (clj->js {:Home {:screen (AppRoot state/app state/markers)}}))
#'my.ns.android.core/c
my.ns.android.core=> c
#js {:Home #js {:screen #js {:$$typeof 60103, :type #object[Function "function (props, context, updater) {
  ...}}}})
my.ns.android.core=> (stack-nav c)
#object[Error Invariant Violation: The component for route 'Home' must be a a React component. For example:

import MyScreen from './MyScreen';
...
Home: {
  screen: MyScreen,
}

You can also use a navigator:

import MyNavigator from './MyNavigator';
...
Home: {
  screen: MyNavigator,
}]
Apparently, I don't create a react component using create-element... How to create a react component from a rum component?

kurt-o-sys11:05:27

Or, stated differently: how to translate:

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    return <Text>Hello, Navigation!</Text>;
  }
}
into rum/cljs (defc AppRoot < rum/reactive pn/react-mixin [app markers] ...)?

kurt-o-sys11:05:11

Or: defc doesn't return a react component, right?

rauh11:05:18

@kurt-o-sys Try invoking c, that should return a react component.

kurt-o-sys11:05:46

(c)? c is not a function (it's a map)?

kurt-o-sys11:05:57

my.ns.android.core=> (c)
#object[Error Error: Invalid arity: 1]
G__10184


eval code
[email protected][native code]

rauh11:05:47

@kurt-o-sys Sorry, I meant AppRoot

kurt-o-sys11:05:00

🙂 Well, I actually invoked AppRoot:

(def c (clj->js {:Home {:screen (AppRoot state/app state/markers)}}))
The js code I have to invoke is:
StackNavigator({
  Home: { screen: <some react component> },
});
Where <some-react-component> is the AppRoot, which I invoked as (AppRoot state/app state/markers). Still, it complains it's not a React component... Let me try something else.

rauh11:05:29

So basically this is the problem since often the JSX folks never quite explain what JSX expands to. It becomes easy when you know this.

rauh11:05:47

<TheComponent ...> get's transpiled to a call to React.createElement...

rauh11:05:00

In CLJS we don't have any of that... So we have to do it manually.

kurt-o-sys11:05:46

ok... I have a create-element function somewhere... sec.

kurt-o-sys12:05:48

my.ns.android.core=> (def c (clj->js {:Home {:screen (create-element (AppRoot state/app state/markers))}}))
#'my.ns.android.core/c
my.ns.android.core=> c
#js {:Home #js {:screen #js {:$$typeof 60103, :type #js {:$$typeof 60103, :type #object[Function "function (props, context, updater) {

      if (process.env.NODE_ENV !== 'production') {
        process.env.NODE_ENV !== 'production' ? warning(this instanceof Constructor, 'Something is calling a React component directly. Use a factory or ' + 'JSX instead. See:  : void 0;
      }

      if (this.__reactAutoBindPairs.length) {
        bindAutoBindMethods(this);
      }

      this.props = props;
      this.context = context;
      this.refs = emptyObject;
      this.updater = updater || ReactNoopUpdateQueue;

      this.state = null;

      var initialState = this.getInitialState ? this.getInitialState() : null;
      if (process.env.NODE_ENV !== 'production') {
        if (initialState === undefined && this.getInitialState._isMockFunction) {
          initialState = null;
        }
      }
      !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getInitialState(): must return an object or null', Constructor.displayName || 'ReactCompositeComponent') : _prodInvariant('82', Constructor.displayName || 'ReactCompositeComponent') : void 0;

      this.state = initialState;
    }"], ...}}}
my.ns.android.core=> (stack-nav. c)
#object[Error Invariant Violation: The component for route 'Home' must be a a React component. For example:

import MyScreen from './MyScreen';
...
Home: {
  screen: MyScreen,
}

You can also use a navigator:

import MyNavigator from './MyNavigator';
...
Home: {
  screen: MyNavigator,
}]
...


eval code
[email protected][native code]
figwheel$client$utils$eval_helper
nil
my.ns.android.core=>

kurt-o-sys12:05:07

and:

(defn create-element [rn-comp opts & children]
  (apply js/React.createElement rn-comp (clj->js opts) children))

rauh12:05:39

AppRoot already returns a react element no reason to call create-element

kurt-o-sys12:05:50

Actually, this is the code that I have to 'translate':

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    return <Text>Hello, Navigation!</Text>;
  }
}

const SimpleApp = StackNavigator({
  Home: { screen: HomeScreen },
});
I wonder if (defc xyz ...) transpiles to something like class xyz extends React.Component {...}. If so, I have no clue why react-navigation` fails to agree that it's a react component 😛.

kurt-o-sys12:05:48

I expect this is right: StackNavigator({Home: { screen: AppRoot }}); -> (stack-nav. (clj->js {:Home {:screen (AppRoot state/app state/markers)}}))

rauh12:05:30

In that case you might need (:rum/class (meta (AppRoot ....)))

kurt-o-sys12:05:42

oh... ok... let's try 🙂

rauh12:05:45

But I doubt that'll work

rauh12:05:52

Because the component has no clue how to create the rum component.

kurt-o-sys12:05:14

right, that will not work:

my.ns.android.core=> (def c (clj->js {:Home {:screen (:rum/class (meta (AppRoot state/app state/markers)))}}))
#'my.ns.android.core/c
my.ns.android.core=> c
#js {:Home #js {:screen nil}}

kurt-o-sys12:05:39

my.ns.android.core=> (meta (AppRoot state/app state/markers))
nil

kurt-o-sys12:05:17

no metadata 😛?

rauh12:05:25

Argh sorry, it'd be (meta AppRoot). but yeah still not a good idea

rauh12:05:47

So in that case you'd have to wrap the rum components into a class.

kurt-o-sys12:05:52

oh, sorry... got it

rauh12:05:04

Quite a bit of work... 🙂

kurt-o-sys12:05:37

=> ((meta AppRoot) state/app state/markers)
#object [cljs.core.Atom {...}]
Hmmm... and now wrap this in a class?

rauh12:05:57

Try it out.. but you won't be able to to pass any arguments.

kurt-o-sys12:05:16

=> (def create-class (.-createClass React))
=> (create-class (AppRoot state/app state/markers))
#object[Error Invariant Violation: ReactClass: You're attempting to use a component as a mixin. Instead, just use a regular object.]
[email protected]://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:1617:24
[email protected]://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:22076:90
[email protected]://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:22270:25


eval code
[email protected][native code]
figwheel$client$utils$eval_helper
nil

kurt-o-sys12:05:50

=> (support/create-class ((meta AppRoot) state/app state/markers))
#object[Error Invariant Violation: createClass(...): Class specification must implement a `render` method.]
[email protected]://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:1617:24
[email protected]://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false:22285:86


eval code
[email protected][native code]
figwheel$client$utils$eval_helper
nil

kurt-o-sys12:05:20

Let's try the other way around: translating

class HomeScreen extends React.Component {
                                          static navigationOptions = {
                                                                      title: 'Welcome',
                                                                      };
                                          render() {
                                                    return <Text>Hello, Navigation!</Text>;
                                                    }
}
to cljs?

kurt-o-sys12:05:22

(defc HomeScreen
  []
  (text "Hello, navigation"))
Right? How to add static navigationOptions = {title: 'Welcome' };?

rauh12:05:11

Start with that defc, yes. Then pass in (:rum/class (meta HomeScreen))

kurt-o-sys12:05:21

=> (stack-nav. (clj->js {:Home {:screen (:rum/class (meta HomeScreen))}}))
#object[NavigationContainer "function NavigationContainer(props) {
      babelHelpers.classCallCheck(this, NavigationContainer);

      var _this = babelHelpers.possibleConstructorReturn(this, (NavigationContainer.__proto__ || Object.getPrototypeOf(NavigationContainer)).call(this, props));

      _this.subs = null;

      _this._handleOpenURL = function (url) {
        var parsedUrl = _this._urlToPathAndParams(url);
        if (parsedUrl) {
          var path = parsedUrl.path,
              params = parsedUrl.params;

          var action = Component.router.getActionForPathAndParams(path, params);
          if (action) {
            _this.dispatch(action);
          }
        }
      };

      _this.dispatch = function (action) {
        var state = _this.state;

        if (!_this._isStateful()) {
          return false;
        }
        var nav = Component.router.getStateForAction(action, state.nav);
        if (nav && nav !== state.nav) {
          _this.setState({ nav: nav }, function () {
            return _this._onNavigationStateChange(state.nav, nav, action);
          });
          return true;
        }
        return false;
      };

      _this._validateProps(props);

      _this.state = {
        nav: _this._isStateful() ? Component.router.getStateForAction(_NavigationActions2.default.init()) : null
      };
      return _this;
    }"]

kurt-o-sys12:05:23

but no arguments, so to pass arguments, I may have to nest components? (Or is there another solution?)

kurt-o-sys12:05:06

Thanks a lot already! It's really weird, but it does seem to work 😛