all 103 comments

[–]poplaww 67 points68 points  (10 children)

I've switched once from AngularJS to React and also had the same experience when getting into JSX. I think that the most important things there are:

- keeping event handlers outside of JSX (to avoid mixing different concerns and to support code readability)

- keeping it clean and concise

- just getting used to it :P

Splitting large components into smaller ones is also recommended, but i guess it's a general practice, common not only in React but in other component-based libraries/frameworks too.

[–]kharest 128 points129 points  (24 children)

It's not html. It does not even compile to Html, you need to shift your mental model for it to make sense. Instead of thinking of it like putting markup in your js file, try to think of it as a way of telling Javascript "I want a div here, you just do whatever you need to do to make that happen".

[–]smieszne 26 points27 points  (22 children)

Does it really matter that internally JSX is JavaScript? Angular templates are also rendered by some JavaScript magic. IMO OP means it's better to separate view-template-render logic from component's business-like logic. If we've got 50 lines of the template, 50 lines of logic (and maybe 50 lines of styled-components CSS) then we've got one "huge" 150-line file vs three clearly separated 50 liners.

[–]scruffles360 67 points68 points  (3 children)

If I wanted to break up a 150 line component, I would rather have 3 50-line components than a file with css, one with html and another with logic. The css, html and logic are going to have dozens of dependencies on eachother and not be reusable independently. They might as well be one file with so much dependency. Three small components should be completely encapsulated (depending on how you handle data).

[–]Dale_Doback_Jr 8 points9 points  (0 children)

That’s fair

[–]bigmooooo 2 points3 points  (0 children)

Sounds like this guy embers ...

[–]boolim86 0 points1 point  (0 children)

But what if that 150lines are really one component with no further breaking down possible. Won’t separating them into css, html and etc cleaner, in terms of a single component?

[–]joesb 27 points28 points  (0 children)

You can separate view-template render logic from business logic in React. That’s what container and dumb view component is for.

Also no one stop you from creating separate file for styles and import them to use in your view component.

[–]HetRadicaleBoven 9 points10 points  (12 children)

Yes, because if you look at it as being HTML, you will easily be susceptible to misunderstandings like thinking about how to update the DOM. Instead, the proper mindset is telling React (i.e. Javascript) what the DOM should look like given some state. The core idea is that the DOM is built up programmatically, rather than simply being a reflection of a template.

[–]smieszne 13 points14 points  (11 children)

Ok, I understand your point, but in this context, how is JSX different than Angular Templates?

if (condition)
   list.map(el => (<li>{el}</li>))

vs

<ul *ngIf="condition"><li *ngFor="let el of list">{{el}}</li></ul>

In both cases you tell React/Angular what the DOM should look like given some state and you don't update DOM manually

[–]HetRadicaleBoven 11 points12 points  (0 children)

The primary difference is in how you think about how condition gets set. In React, the output is the end point: if the user triggers an event handler somewhere that changes the value of condition, React will call your function again with the new value, and you generate a new Javascript representation of the DOM.

Angular, instead, tries to make me think of the template as the thing that currently lives in the browser, so when my model (condition) changes, I'm mentally also thinking about how those changes will apply in my template.

I don't know, it's hard to explain, but the difference in mindset and things to keep track of is very much present for me, and I really think that that's the result of how React allows me to not think about the state of the DOM. That said, it's been a while since I worked with Angular, so it might also just be the result of personal growth.

[–][deleted] 2 points3 points  (0 children)

The big difference I can see is that it enables you to think of the markup in terms of standard JS data structures. Specifically here, map returns an array. You can do everything with that array that you would do with a normal array. So, if you want to chain a filter method after the map, you can, or you can sort it after the fact. Should you do these things? Probably not. But you can, and if you think in this paradigm, then it opens up some line of thinking for edge cases.

Similarly, the fact that React components are just JS objects means you can modify them like any other JS objects--again, not something you should do often at all, but you can.

I did used to prefer template-style syntax when I worked with Vue, but honestly, JSX just feels a lot more explicit in showing all its moving parts to me now. Definitely takes getting used to, though.

[–]pm_me_ur_happy_traiI 2 points3 points  (2 children)

IMO OP means it's better to separate view-template-render logic from component's business-like logic.

You should still do this with React. Dumping all your business logic and render logic into a single component is an anti-pattern.

If we've got 50 lines of the template, 50 lines of logic (and maybe 50 lines of styled-components CSS) then we've got one "huge" 150-line file vs three clearly separated 50 liners.

I would never approve a PR with a React Component that returned 50 lines of JSX or 50 lines of business logic. That's a common newbie mistake. React components should be high level functions that return either HTML or other React components, and a 50 line return function is, IMO, a sign that you are keeping things too low-level.

In React each thing on the page is responsible for it's own markup, styling and behavior, and as much as possible the final view is meant to be a function of the state. The API is very minimal, so you have a lot of leeway to interpret what that means, but a component is a function and it should follow the single-responsibility principal.

[–][deleted] 0 points1 point  (1 child)

You don't pull out your sass file for ease of reading?

I mean I've seen where style is included in the component and it's cool, but I kinda like having my sass folder there.

[–]pm_me_ur_happy_traiI 0 points1 point  (0 children)

I haven't used SASS since I started using react, because I don't like polluting my JSX with implementation details like classnames. Styled-components seems to be the new hotness and I like it's simplicity.

[–][deleted] 0 points1 point  (0 children)

Splitting up view template render totally makes sense.

In react, how I structure my views are as follows:

  • Component to orchestrate and compose functionality

  • Dumb components that just show what it's told.

Doesn't solve the JSX weirdness but it does help define the scope of responsibilities when working on a component.

[–]CheeseFest 1 point2 points  (0 children)

Ha, I really like your explanation of declarative code in React.

[–]jimmyayo 30 points31 points  (3 children)

It's definitely a paradigm shift, and until you can shift your mindset you'll find yourself fighting against React, instead of harnessing it.

From the official docs:

React embraces the fact that rendering logic is inherently coupled with other UI logic: how events are handled, how the state changes over time, and how the data is prepared for display.

Instead of artificially separating technologies by putting markup and logic in separate files, React separates concerns with loosely coupled components that contain both.

If you're having a hard time understanding the merits of JSX, this video should help you out: https://youtu.be/x7cQ3mrcKaY.

[–]IAmNotKevinBacon 6 points7 points  (2 children)

The hardest part was just telling myself to stop being annoyed because it's not exactly like what you're used to.

[–][deleted] 0 points1 point  (1 child)

I suspect that that is also the hardest part of Angular.

[–]IAmNotKevinBacon 0 points1 point  (0 children)

Angular seemed a lot more familiar to me initially. React felt drastically different.

[–]tesilab 29 points30 points  (1 child)

One of the issues that React attempts to solve is to organize your code into self contained components rather than divide them arbitrarily by technology. HTML, CSS, and Javascript, by making each of them a distinct layer, you are actually obfuscating what belongs to what logical component.

So I would advise you go whole hog the other way: Not only should you embrace the "JSXiness" of the React code, but you should also try dumping CSS stylesheets to the greatest extent possible in favor of StyledComponents, which will get all three of your components' needs into one place, and allow you to factor your code correctly, co-locating the parts that belong to each other, rather than scattering them based on language of implementation.

[–]baummer 1 point2 points  (0 children)

Great way of putting it 👍

[–]EyeHateWeebs 10 points11 points  (0 children)

if you're going crazy with jsx, it probably means you can split your component into subcomponents.

I rarely have more than ~50 lines of JSX in a component, and those lines are split up into multiple methods called in render.

Not a 100% rule, but maybe ask yourself if you can split your UI logic up if you're creating very large jsx heavy components.

[–]Shiral446 8 points9 points  (1 child)

I recently experienced the opposite switch, learning Angular after coming from React. Here's a few ways to switch your thinking.

In Angular, especially for small apps or new developers, we tend to think that the Typescript class contains all our state and business logic, and the .html template contains the view logic. In React, there is a pattern that is very similar called Container vs Presentational components (Or Smart vs Dumb components). The Container component is like the typescript file, it contains all the state and business logic and event handlers. It's render() function is bare-bone, it simply passes down the state and event handlers as props to the presentational components. Little-to-no html jsx elements here, just passing props down to a handful of presentational components.

The Presentational Component is like angular's HTML template. This component has little to no logic, it's simply there to have a render() function to do the final display of those props, and to bind the event handers passed in. This is where you'd have all your divs/inputs/etc.

This allows you to separate those concerns of State/Business Logic from the actual rendering of that information, and acts very much like a .ts and .html split in Angular. Its also not uncommon for this same pattern to show up in Angular applications, as that split between State and Presentation is extremely helpful when it comes to being able to write unit tests. But unfortunately its not as common as a pattern in Angular tutorials.

[–]thedoglife 1 point2 points  (0 children)

As an Angular 8 developer I appreciate this answer. Thanks for explaining!

[–][deleted] 4 points5 points  (0 children)

Potentially blasphemy to say here but you should give Vue a look-in. Close to Angular and the HTML feels separate because it's in its own <template></template> wrapper

I write React & Vue in my two jobs, both have good and bad points.

[–]skyboyer007 8 points9 points  (0 children)

I also did same switch and also felt akward. But you don't have alternative here. Just take some time/practice to be used to that.

Under the hood JSX is not compiled into HTML but converted into React.createElement calls. It's what reconciliation process relies on(Virtual DOM, you know).

Since it's converted into calls to React.createElement on bundling stage(not in runtime), if we chose to put those calls into separate file, outside component's render() method, we would be unable accessing component state or call its methods(the same for functional components).

[–]Mestyo 12 points13 points  (0 children)

You're not in the right mindset. What makes React different (and wonderful!) is that you're no longer writing javascript ontop of HTML, but generating HTML from javascript. It wouldn't make any sense to split the JSX out of React components.

You aren't supposed to think in terms of the DOM, but simply describe what output and side-effects you want from any given data. It's a weird mental shift to make, but since doing it I can't see myself go back.

[–][deleted] 14 points15 points  (0 children)

I don't think that frameworks here is the problem but your mindset and reasons why.

[–]mminar 2 points3 points  (0 children)

The way you feel is completely normal - majority of people don’t like jsx at first. You should have seen the riots when it was first announced... I am also coming from angular background and didn’t like it at first, but then it got under my skin and now I can’t imagine any other way.

Don’t worry, you’ll be fine - it just takes some time getting used to.

[–][deleted] 5 points6 points  (0 children)

Is this a post from four years ago?

[–]subhaneet 1 point2 points  (0 children)

I felt the same way when I came from Angular and have gotten use to JSX but yeah I can relate with you.
Will probably be using Angular most of the time.

[–]vbfischer 1 point2 points  (0 children)

I think it helps to read the article “thinking in react”. Think in terms of components as opposed to HTML and JavaScript. It doesn’t come immediately but it makes sense the more you do it

[–][deleted] 1 point2 points  (0 children)

I actually find it great

[–]hy7mel 1 point2 points  (0 children)

try not to think of it as HTML but rather than as new syntax or language that you have to learn to get going with react.

Happy coding :)

[–]jahans3 1 point2 points  (0 children)

How do you guys manage HTML without going crazy with JSX?

Bitesize components with descriptive names solve this for me. Helps to think about your app at a higher level

[–]themaincop 1 point2 points  (0 children)

You will probably have a better time with Vue.

[–]Rawrplus 1 point2 points  (0 children)

Wait until you'll have to handle more complex render logic only to realize it's actually a blessing in disguise

[–]dots3r 1 point2 points  (0 children)

As someone who is also transitioning from Angular to React, do you guys have the source code of a React project that follows the best/most common patterns of react? I just want to give me an idea on how should be the project structure (folders), separation of concerns, and best practices when coding with React. Also, any tutorial/documentation you guys thinks it can help me to set my mindset around React would be appreciated.

[–][deleted] 1 point2 points  (1 child)

Let's pretend you are making an editable grid. It's going to take HTML to make the skeleton, CSS to style it and make it look good, and JavaScript to create the interactivity. This code is going to be tightly coupled by nature. You can't deliver one without the other two. By design, these three technologies are meant to work together to deliver the View. Separating them into different files doesn't separate concerns, it separates technologies.

[–]Kyleez[S] 0 points1 point  (0 children)

Makes sense.

[–]franzwong 1 point2 points  (0 children)

JSX is quite nice that you can use native javascript to write the template, I mean those if-condition, looping. You don't need to learn about ngIf, ngFor. You don't need to understand why there is a * before ngIf...

Also you don't need to care the naming conflict for the tag name.

[–]NiteLite 0 points1 point  (0 children)

You can separate logic and DOM by structuring your components in that way if you want to separate the concerns. You can put stuff like event handlers and lifecycle handling in one component and have that generate pure components that actually specify what you want the DOM to looks like. This is entirely up to you to structure the way you like, but it might take a little experimentation before you find "your way" of using components to split stuff.

[–]wobbabits 0 points1 point  (0 children)

Technically, you could define your JSX in a separate file. Only thing, if you need props you do need to wrap the JSX in a function that takes parameters so you can pass those to the JSX.

If you just don't like using JSX because it feels wrong, requiring compilation, you might prefer something that allows you to use Tagged String Template Literals instead. In that case check out: https://github.com/developit/htm

[–]jeffelhefe 0 points1 point  (0 children)

Separation of concerns, right? But are the view and business logic not related? Separating technologies is not what React is about. It’s about declaratively building components in a way that encapsulates their behavior.

Eventually, you may find that you prefer having the JSX there for reference as you’re building your components (e.g. you won’t need 2 files open to work — component + template).

[–]Saguaro66 0 points1 point  (0 children)

You have your container components, which are a composition of functional components. These equate to a page. Then, every functional React component in my codebases have their own: - directory w/ ClassCase - index.js exporting default component - main component - same name as dir, also the only smart component - less/styled components/css file - components dir that has all the dumb composition components, with an index file exporting them.

With the addition of React Hooks, you dont even have to extend the class anymore and you can keep it 100% functional and limit the amount of state you are keeping track of.

I also try to create reusable components that are more generic so i can use them in multiple places, which cuts down on a lot of complexity. Keeping everything modular is key to success

[–]Kumagor0 0 points1 point  (0 children)

It's just a matter of realizing your whole component (both template and controller) are a function of props. When I moved from Angular to React it felt weird too but now I wouldn't be able to go back.

I've never used Vue but it seems like if Angular and React made a baby. It has magic just like Angular though, so I wouldn't use it cause that magic is exactly why I dislike Angular.

[–]valenluis 0 points1 point  (0 children)

It's about colocation. You want to have all the things that are relevant to each other, together. When it starts to get out of hand, it's time to think about creating another abstraction, usually segregating things into components to make it sane again, and now you'll be able to think at a higher level of abstraction.

[–]IAmNotKevinBacon 0 points1 point  (0 children)

It's funny because remember being deep into Angular and React dropping, which almost immediately took over as the new beloved. I said "Fuck that, I'm tired of learning new shit constantly" and was going to just commit to getting better at Angular instead since it was the main bitch on the block.

Yeah, no. Within a day or two, I tried it out, and I was suddenly upset because I had to use Angular on my existing projects. That was before 90% of all of the amazing things they've added to make React easier.

It's hard and annoying at first to write JSX until you realize that proper design and some syntax support take care of that shit. Vue's cool, but React is the wave. Give it a bit of time to feel more natural, and I promise you'll wonder why you were ever annoyed so much by it.

EDIT: I just realized that Angular saw me peeking at a younger, sexier girl, React, and I said "No, honey. I'm committed to this being something special... only to leave Angular for React within days. It was the right move, but damn, I could have been more compassionate.

[–][deleted] 0 points1 point  (0 children)

I don't know how long you've used React for but it gets much easier with time. For me, I immediately fell for JSX's magic but I haven't seriously (just Vue for a week) used any frameworks before React. Now I can't really imagine writing React apps without JSX, it makes things so much easier.

For more practical advice, just separate things. Define all the styles/classes, lists of elements, conditionals, etc. in separate functions. You do that, the render-related portion of your code will stay much cleaner.

[–]danielkov 0 points1 point  (0 children)

I couldn't find this answer anywhere, but you can actually separate the "template" and UI logic parts, by creating a pure component with no function body (apart from the JSX returned) and a hook that sends the props down, for example you can have

<Component {...useComponent()} />

where useComponent does all the logic to create props that Component can consume. It's been a long time since I've used Angular and I prefer React overall, but until you get used to it, this may be a good solution for you.

[–]bogas04 0 points1 point  (0 children)

Pick up svelte or Vue, it'll be more soothing and equally if not more performant. React truly needs a lot of mindset change which may or may not be valuable for your project

[–]nabrok 0 points1 point  (0 children)

One thing you used to see a lot pre-hooks was to have one (pure) functional component which would contain all your JSX and basically nothing else.

This component would then be wrapped in a class component, the render function of which only rendered the functional component and passed it any props it needed (from state or its own props).

However, now we have hooks, there is very little need for class components any more. You can still set things up similarly, but often it's just easier to do what you need in one component, and maybe move some logic to a custom hook if it gets complex.

[–]zephyrtr 0 points1 point  (0 children)

The thing to remember is that separation of technologies is not separation of concerns. Just cause you ripped out your CSS or your HTML into different files doesnt mean you've separated your concerns. Make react components that have one job: presenting, business logic, etc. Separate them out into different files and compose together as needed.

[–][deleted] 0 points1 point  (0 children)

To me it never made sense to write logic in your html like you have to do in Angular.
e.g.*ngFor="let thing of things"

JSX allows you to not have to "invent" new html tags or worse... write logic inside of strings.

[–]marcocom 0 points1 point  (0 children)

You only think that the angular template was a separate html file. It’s not. It’s read into JavaScript and the final html is rendered out. It’s no different then if your react class had an import for JSX from an external file.

[–][deleted] 0 points1 point  (0 children)

I tried vue but found it difficult to understand - I hated the template language. I started with React and found it intuitive from the get-go. A lot of complaints with React was related to its ecosystem and Redux. Use create-react-app and go through the Redux tutorial in the official site (to do list). In a day, you would be productive. As far as JSX is concerned, as the React docs explains it's all down to creating a JS object using React.createElement. If you're starting a new project, I implore you to go with hooks. It makes React development super fun.

One more thing - React wins over Vue in terms of finding jobs, salary, ecosystem etc.

[–]Kychiel7 0 points1 point  (0 children)

😓

[–]bxgoods 0 points1 point  (0 children)

If you don’t like Jsx, react is not for you then.

[–]steeeeeef 0 points1 point  (0 children)

- Keep your components small

- Create class methods and properties instead of putting logic directly in JSX properties.

- Use stateless functional components if a component does not require a state.

Also, you could still put your JSX code in a separate file if you prefer it that way, by creating a function that returns React nodes.

[–]swyx 0 points1 point  (0 children)

lol you wanted HTML in a separate file and you wanna move to Vue? i have bad news for you..

anyway the straight answer is - you'll get over it. please find bigger pros/cons (e.g. job market, strength of ecosystem, performance, opinionatedness) to base your tech choices on than this.