ViewModel for React Alpha

Hi @manuel , Might be another teething issue here? The <Person/> component is throwing:

While building for web.browser:
   imports/App.js:10:4: Adjacent JSX elements must be wrapped in an enclosing tag (10:4)

10:4 being the <Person/> tag.

You might be putting both Components on the same file. This is a limitation at the moment. Each component has to be in its own file.

It could also be that thereā€™s one convention in ViewModel react: if you donā€™t add an import for a sub component itā€™s assumed to be in a subfolder of the same name. If you donā€™t like that convention then add the imports as usual.

So in your case you might have App and Person on the same folder but not adding an import explicitly.

Please let me know if that helps.

Hi @manuel,

I have the Person component structured as youā€™re instructed. so:

ProjectName/imports/App.js - works ok
and
ProjectName/imports/Person/Person.js - is not showing

So ,the App.js file is showing Hello World in the browser, and is structured like you mentioned - ā€™ < Person /> ā€™ just under the <h1>

It is still giving me the same error.

Iā€™ve also tried manually importing it:

import { Person } from '/imports/Person/Person';

to no avail.

Iā€™m very sorry itā€™s been a pain for you to test ViewModel. Your experience should have been much smoother than this. I canā€™t apologize enough.

If you can bear with me for a little bit longer, please create a git repo with your project as you have it. It has to be a minor detail (which should be documented).

1 Like

Hi @manuel, thanks.

Check this here . https://github.com/polonski/ViewModel-React/

But Iā€™m afraid itā€™s nothing more than the result of the instructions on how to set this up.

I hope you can find if anything is out of place.

Many thanks

Did you try to wrap all elements in your App.js render method?

<div><h1>Hello world</h1> <Person/></div>

1 Like

Aha. @XTA , thanks man!

Iā€™m wondering why<h1>blah</h1> without the enclosing div works ok but anything beyond does not?

Looks impressiveā€¦

A4 paper sheet with short documentation would be great.
I meanā€¦ none would use it just to replace class definition with short one, isnā€™t it?
You would probably want to include it into your projects and try some things instantly.

Just a suggestion, though.

With React you canā€™t have a component return multiple elements. Notice how in my example I wrap the h1 and the Person elements in a div. Iā€™ll include this in the docs.

Itā€™s a React annoyance I canā€™t get around with transpilation.

1 Like

You may. As an array.

Nope. If you try to return an array you get an error:

var Hello = React.createClass({
  render: function() {
    return [<div>Hello</div>];
  }
});

Uncaught Invariant Violation: Hello.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

1 Like

Damn, you are right.
For some reason I was sure it worked for me.

Hi @manuel, any chance to come up with a boiler plate demo project ?

Aye. Iā€™ll make a few (Meteor+React, Meteor+React+Blaze, Webpack, maybe more).

1 Like

Iā€™m working on a better introduction to ViewModel but itā€™s hard to explain/convince people whoā€™ve never tried it that this way of doing things results in simpler and less code, not only it reduces boilerplate and ceremonies, but your application logic and architecture is simplified a ton.

For example the most common feedback I get is something like ā€œI replaced part of my app with ViewModel, it took half the code, itā€™s a lot simpler, and difficult bugs I had before magically went awayā€. Itā€™s hard to explain that without people going ā€œyeah, rightā€¦ā€

And then you have small things like reducing unnecessary Reactā€™isms. With ViewModel you can write normal HTML:

<div class="header" style="color: red">Hello</div>

I guess the issue is that simple examples just donā€™t cut it. You have to try it with something non trivial and letā€™s face it, few people are inclined to do so. And I get it, trying any library beyond simple examples requires an investment of time and effort which might not pan out so the easiest thing to do is reject it.

1 Like

I think people are just getting tired of learning again and again and again, and want to get back to actually building stuff. Especially when you step back from all the code-side hype and look at the actual apps being built. Your average user could never tell if you built your app in jquery and soap api, or if you used angular 3, ES9 and graphFalcorā€¦ I bet if you surveyed them they would hardly notice a single-page app vs server-side routing.

I noticed the guy who built cycle.js is all bitter that redux/react is more popular. I think he just doesnā€™t get that people donā€™t want to learn an entire new library for some minor semi-negligible syntax improvement.

Not to down VM, just saying I can see how it is hard to get people to pick it up. I think javascript fatigue is starting to weigh on basically everyone who isnā€™t dan abramov.

1 Like

Itā€™s a crowded space no doubt. I donā€™t know what makes a library or framework ā€œstickā€ but Iā€™m pretty sure marketing and company backing weighs much more than merit. I mean, if you read the reasons why people like React, the same can be said x2 about Elm (and then some).

Cycle.js is in a tough position (same as Elm) because it isnā€™t an addon, itā€™s a full blown view layer. One that isnā€™t very succinct by the way.

ViewModel is in a weird position because it isnā€™t orthogonal to React, itā€™s right on top of it, so itā€™s in front of you more than other helper libraries. At the same time itā€™s a bit like Elm where even though you can use it in an existing application, you donā€™t really see the benefit if you do one component with it.

1 Like

I thought I should add this to the thread:

The syntactic sugar in ViewModel is nice but itā€™s far from being what reduces your code the most. Itā€™s all the run around, dances, and complex patterns you donā€™t have to deal with anymore. Letā€™s take ā€œstate managementā€, the 2 most common ways of dealing with state that needs to be shared between components are:

  1. Let components reference one another so they can get the state they need. The problem here is that you want to share a banana but you end up keeping track of the gorilla tribe.

  2. Store the entire state of the application in a central place. You no longer need to keep track of the gorillas, but now you need a jeep, a machete, and know your way through the entire jungle just to share a banana.

ViewModel takes the simple approach of only sharing the state that needs to be shared and thatā€™s it. Components donā€™t reference one another, you keep the shared state to a minimum, and components are explicit about which state can be modified by someone else.

It looks like this:

ViewModel.share({
  house: {
    address: ''
  }
})
ComponentA({
  share: 'house',
  render() {
    <div b="text: address" />
  }
})
ComponentB({
  share: 'house',
  render() {
    <div b="text: address" />
  }
})

Now components A and B have access to the same address and nothing else. You wanted to share a banana and you did just that, nothing else.

4 Likes

I felt the same about gorilla and banana alone my way working out Meteor/React/Redux :slight_smile:

Probably others also wish to know how VM address what Redux advocates most:
i.e. pure functional state update (one way flow) and time travel ability for states ?

Hi @manuel,

Iā€™ve had trouble using some basic material-ui.

Using the AppBar http://www.material-ui.com/#/components/app-bar Info Bar :

          <AppBar
	    title="Title"
	    iconElementLeft={<IconButton><NavigationClose /></IconButton>}
	    iconElementRight={
	      <IconMenu
	        iconButtonElement={
	          <IconButton><MoreVertIcon /></IconButton>
	        }
	        targetOrigin={{horizontal: 'right', vertical: 'top'}}
	        anchorOrigin={{horizontal: 'right', vertical: 'top'}}
	      >
	        <MenuItem primaryText="Refresh" />
	        <MenuItem primaryText="Help" />
	        <MenuItem primaryText="Sign out" />
	      </IconMenu>
	    }
	  />

It renders, but the <IconMenu> is not showing.

Is there a ViewModel speak version of this that would work? I notice you mention we can use normal attribute declaration inside the html element, but this somehow seems not to be working here?

This is on gihub here for reference https://github.com/polonski/ViewModel-React

Many thanks