Pains with React + Semantic UI

I recently started a project to explore React styled with Semantic UI. What I found was that the React world didn’t have strong support for Semantic UI even though everyone makes out that there are alot of components to choose from.

There are two abandoned projects:


and one in it’s infancy (just found this today after I decided to abandon react):

I imagine there is more support for bootstrap and had I not chosen Semantic UI, I would have probably persisted a bit longer.
In this case, Blaze is more suitable because it is fine with Semantic’s native javascript code doing DOM modification in the onRendered function.

On working with JSX, I tried to be open minded about it, but overall it felt very messy and to get it to a point where it wasn’t messy, it meant componentising almost every field in a form (dropdowns, n-way radio check buttons, anything more complex than a straight input). This probably wouldn’t have been such a issue had there been semantic-ui-react components.
Another verbosity was looping

{
    _.map(list, function (i) {
        return (
            <div>
               // item code here....
            </div>
        );
    }
}

vs angular or blaze and this thing just looks monstrous! With the other frameworks I can typically fit a form in 1-2 pages, have all the logic and markup in one place so there was very little cognitive load when scanning a template. With react, to reduce cognitive load, i’d have to create dozens of components per page, and they are not necessarily reusable.

So even though I’m highly tempted by react native, I’m going back to Blaze until there’s better SUI support! :smile:

1 Like

Isn’t that because Semantic UI is React-compatible out of the box, so it doesn’t really need any special integration?

http://semantic-ui.com/introduction/integrations.html

Semantic UI components are designed to be compatible with libraries that tightly manage UI lifecycle like React. No special bindings are needed.
Most components use mutation observers to watch for changes in internal state, and all components are built with initialize, refresh and destroy methods which will regenerate, refresh cached values, and teardown components.

But I went back to Blaze too, React is too often just overcomplicating simple things.

3 Likes

Coincidentally I started integrating them yesterday for a new project, using meteor-webpack-react. Couldn’t get react-semantic-ui working, but react-semantify has been working fine so far.

If I understood correctly, you are pained by the apparent verbosity and not really any technical issues? Initially it might feel like the component wrappers are redundant, but the real benefit would be when you start composing them to build larger components. And you’ll love it when you can change aspects of components (both low and high level ones) by changing code in just one Javascript class. But if you’re just building something simple that might not undergo a lot of changes in the future, then Blaze might be a better fit.

1 Like

Isn’t that because Semantic UI is React-compatible out of the box, so it doesn’t really need any special integration?

Yeah, but I feel it’s still useful to have React Component wrappers. Something like react-bootstrap, they have done a great job and it’s a very active project.

And because semantic-ui is supposed to play well with reactjs, it might not be too difficult for me to contribute to react-semantify if I need to wrap more components.

I’ve not yet begun tinkering with React, although am keeping an eye on it.

To my understanding, you could mix Blaze and React, such that you could create a layout in Blaze and insert form components created with React or inversely, create a layout in React and insert a form designed with Blaze.

Is that not correct?

Does that have an obvious downside other than being blasphemy for those belonging to the react-camp?

Using React components in Blaze templates is supported by Meteor’s official React package.

For the other way round, don’t think it would be “blasphemy”. ReactJs provides sufficient hooks to integrate with other libraries, which should enable you to use Blaze templates in React components. That helps a lot if you don’t want to reinvent the wheel, or migrate legacy code.

There are 2 potential problems or downsides that come to mind:

  1. If the external library modifies DOM in an unpredictable way, it could cause React Invariant Errors. This at least used to be a problem in previous versions of React (I am stuck with 0.10 for a long time)
  2. For UI-performance-critical complex apps, you might want to make full use of the React lifecycle APIs and do all DOM manipulations only via React.
1 Like

@brajt the css integrates nicely, however if you want to do a dropdown, semantic offers jQuery like bindings $('#dropdown').dropdown(opts) but react doesn’t like this as it directly manipulates the DOM. This is why the react-semantify packages exist methinks. To do the dom manipulations the react way.

also, semantic doesn’t have a datepicker and the popular react-datepicker looks out of place with semantic styling around it

@gaurav7 The dropdown thing was the last straw. react-semantic-ui was a good candidate but luke asked the maintainer whether he would update to support SUI 2.0 and the answer was no. I like the props/state idea and how easy it was to separate concerns of parent/child (clearly superior to blaze), but the verbosity basically forces you to declare a component for very trivial cases to keep the render code readable. Loops, conditional elements, conditional classes all need to be declared as variables (else you start getting into very weird looking JSX html syntax) which means you jump from place to place to figure out what the logic is for your template. Four space indentation is crazy with JSX cause you’re already about 12 spaces in before you hit your root <div> element in your render function and if you want to nest a loop, then it’s another 12!

@serkandurusoy yes, in fact i used the accounts-ui-semantic-ui package with accounts-ui to get blaze loginButtons template and then wrapped that in a react component as per my own question here on the forums somewhere. It was a easy way to get accounts functionality going.

All said, I feel that I’m not ready to take the leap just yet (again! darn it!), almost feels like I have to start looking into webpack, reflux, relay just to get my head around the best approach at a full stack platform. Oh wait, that’s why I came to meteor in the first place. Back to basics, now I’m using semantic-ui with autoforms, can happily do .dropdown() in the onRendered function and yeah, even though things are not as componentised, for the little apps I’m doing, it doesn’t matter atm.

2 Likes

@gaurav7 @mordrax thank you for the hints. These will come in handy!

react-semantic-ui didn’t work for me, it kept throwing React is undefined exception when I tried to initialize. Good that I didn’t pursue then; I didn’t know it doesn’t support SUI 2.0 :smile: I am using SUI 2.1.4 with react-semantify because it doesn’t bundle any version of SUI; I’m actually using the latest semantic-ui meteor package along with it.

Well, the pay-offs for writing small components and using liberal composition is the same as defining small reusable functions. One might ask why define so many functions, each consisting of only a few lines! The benefits of such an approach is proportional to how large your app is.

I do agree it’s a bit of mental re-training to get used to JSX when compared with a template based approach. But it’s not difficult, especially once one has realized the advantages of using ReactJs components. A style guide like AirBnB’s JSX style guide should help a bit.

I’m sure this would work if you apply the binding in componentDidMount() method of the component. Or give a shot at react-semantify, its <Dropdown /> component is working fine for me.

By the way, if your goal is only to learn the Meteor framework, then perhaps you shouldn’t learn ReactJs too at the same time. Maybe first get comfortable with Meteor and then try React. Also, Meteor 1.2 is releasing soon with official React support.

1 Like

Funny you should mention that: https://github.com/meteor/javascript

3 Likes

Thanks for the link @robfallows, I didn’t know there’s a forked version by Meteor! Though the one I linked to covers only React and JSX (edited the anchor text to be more clear).

Do you recommend to disable Blaze and use React as the view layer only?

Yes, it has to be made sure that the DOM is ready and attached before applying jquery DOM manipulation (e.g. dropdown) since Semantic-UI uses a lot of jquery. The correct lifecyle method needs to be applied for that

If you want to use Blaze templates inside React, you can use the thereactivestack:BlazeToReact package. It turns your Blaze template into a React component with one line of code and it keeps the reactivity of Blaze :smile:

It works great for the loginButtons as an example:

const LoginButtons = BlazeToReact('loginButtons');

App = React.createClass({
  render() {
    return (
      <div>
        {/* ... */}
        <LoginButtons />
      </div>
    );
  }
});

Looks like SynapsePay is using Semantic UI with React for their app: https://synapsepay.com/v3/signin/#/ Thought I’d post this here if anyone is interested to see sites who are already using it in some way.

Did you actually try this? Because I’ve been using React with Semantic UI for a while now and there’s absolutely no issues with how Semantic UI does thinks because while building the framework, they thought about frameworks like React beforehand so their integration is seamless.

Semantic UI uses mutation observers which work nicely with React component lifecycles etc.

http://semantic-ui.com/introduction/integrations.html

semantic-ui seems to use less which is always a world of pain with meteor.
can people use stylus already?

I’m having an issue where a dropdown with avatar images and usernames isn’t allocating width for the username :expressionless: specifically this example: http://semantic-ui.com/modules/dropdown.html#inline

it works great with raw html, but not in JSX

I just started using react-semantify and it is working fine so far. Version 0.4 is the latest.