Advice on functional React best practices - reactjs

I started working with React a few months ago. Coming from an Angular background it took a bit to get used to react concepts but I started enjoying it super fast.
Over the past two months I have refactored some class based components to functional components using React hooks. I am looking for advice on some best practices here since I am fairly new to functional hooks and there is not a whole lot of solid opinions on best practices. Here are a few
With regards to “unit” testing. the instance in functional React does not exist. I can’t call a function and test it independent of other methods. React now suggests that “we recommend using react-testing-library which is designed to encourage writing tests that use your components as the end users do.” This approach seems more like end to end testing to me. I have certain functions that that do a number of calculation and save to state without any visual changes and re-rendering. How should I test those functions?
I have read that I need to move some of my functions outside of the main exported function and call them in order to have them return a value to update the state with. Is this good practice? Should I export all of these outside functions in order to be able to test them or is this bad practice? If not how do I get to test these pure functions. I have created a very simple example of the pattern I am talking about here
https://codesandbox.io/embed/busy-currying-v09bb
I would love to know your opinions and how you have managed to solve these problems. Any thoughts or insight
Is much appreciated.

You and I are on same boat as since we both have moved to React from Angular. Considering the points you mentioned I would like to share some practices we have been following in our react projects. This has helped us to reduce much efforts in finding and fixing the bugs. Also we could achieve 100% test coverage.
Always create a common libs and keep all the function which has mostly a business logic but no DOM impacts. This reduces the size of stateful components and makes code much better to deal with unit testing.
Stateful component should never have bulk UI JSX. Always create stateless component (pure component) for UI and handle them all though
the container.
Avoid creating functions which returns the pure HTML (JSX). Crate a different file and return a stateless component from there. This
makes Unit testing easy.
This again is entirely depend on the your project structure. In Angular you work with certain set of pre-defined rules of Angular and Test tools like Protractor makes it easy to test.
However React comes with more flexible development approach which has its own downside. If developer do not keep hold on the way he/she writing the app, it gets into a chaotic situation.
PS: I use JEST for the testing and it does job well in terms of unit testing. I also use cypress for UI automation which is a great tool for react UI automation.
Hope I could help!

Related

React App with both Functional and Class components

I know that after the emergence of React Hooks, functional components are able to act almost the same as the class components, and I have seen lately an encouragement wave to use functional components.
My question is, could it hurt in any means to have a hybrid react app with some functional components and some class components? I understand that react would not complain about it, but I am looking for an experienced best practices, did inconsistency with component's types cause any problems?
Any tips are appreciated.
After sometime of using a hybrid project, I came to the conclusion that it is better to use functional components for the whole project. Not for any technical reason, but because of the community support.
Many of the packages today are made with functional components only (or mostly) in mind, having class components may require an additional workarounds to make it work.
Some packages creates a short-hand hooks for easier usage, eventually it becomes the official supported way for using the package, like what happened with react-alert.
Personally, I have function components that don't manage state and class components that do. However, this is not mandatory. With React hooks you can do everything with functions. It is your choice, it won't impact performance much. Functional components can be more performant when used right. Read more here

React component testing: is "enzyme" to test class component and "testing-library" is more to functional component?

I'm struggling to test simple component (functional) that by changing input value should change var in component state, by onChange event.
Seems like as the state and functions are encapsulated in the component, testing-library is more suitable.
Make sense?
Is there any rules/guidelines for when to use which?
Thanks.
It goes against the principles of React Testing Library to be asserting on implementation details such as a components' state.
Instead, the library recommends you to write tests that closely resemble how the user will interact with your code.
From the docs:
We try to only expose methods and utilities that encourage you to write tests that closely resemble how your web pages are used.
Is there any rules/guidelines for when to use which?
This can be a bit of a subjective topic and might greatly vary depending on which team you work on.
Personally, I switched from using only Enzyme(specifically shallow rendering) to using only React Testing Library, and this is what happened:
It improved my developer experience as I feel the tests became way easier to maintain when the code implementation changes.
I am more confident with the tests since they now resemble more how the software is actually used.
Tests are easier to read and more intuitive. Think of clicking this button should display that message, instead of component x should have correct prop y.
I believe Enzyme can do a lot of things that React Testing Library does, however, I would recommend to at least steer away from shallow rendering. It is not considered a good practice
I still haven't found a use case where Enzyme solved a problem that React Testing Library does not. But that doesn't mean it doesn't exist. It just means that RTL suits me well for now.

Why create-react-app changed App.js component to function based component?

As I noticed, it seems create-react-app changed app.js class component based in a function component,
any idea why they did this?
React itself is moving away from class-based components.
A quotes from this doc: Introducing Hooks
In addition to making code reuse and code organization more difficult, we’ve found that classes can be a large barrier to learning React. You have to understand how this works in JavaScript, which is very different from how it works in most languages. You have to remember to bind the event handlers. Without unstable syntax proposals, the code is very verbose. People can understand props, state, and top-down data flow perfectly well but still struggle with classes. The distinction between function and class components in React and when to use each one leads to disagreements even between experienced React developers.
Additionally, React has been out for about five years, and we want to make sure it stays relevant in the next five years. As Svelte, Angular, Glimmer, and others show, ahead-of-time compilation of components has a lot of future potential. Especially if it’s not limited to templates. Recently, we’ve been experimenting with component folding using Prepack, and we’ve seen promising early results. However, we found that class components can encourage unintentional patterns that make these optimizations fall back to a slower path. Classes present issues for today’s tools, too. For example, classes don’t minify very well, and they make hot reloading flaky and unreliable. We want to present an API that makes it more likely for code to stay on the optimizable path.
To solve these problems, Hooks let you use more of React’s features without classes. Conceptually, React components have always been closer to functions. Hooks embrace functions, but without sacrificing the practical spirit of React. Hooks provide access to imperative escape hatches and don’t require you to learn complex functional or reactive programming techniques.

Are there still reasons to use class components if starting a hooks-enabled project?

I'm starting a new project that's based on React >16.8, where Hooks are now available and stable. I've played around with them and really like what they offer, and would like to adopt them as much as possible in my project. My question is.. how much? Is there any reason for them to not be 100%?
Since functional components are now offering the full arsenal of functionality that class components do, are faster, are much easier to write and much easier to read, are there still reasons to use class-based components?
At the time of writing this, there are only a few small edge cases not covered by functional components using hooks (see this FAQ) such as getSnapshotBeforeUpdate and componentDidCatch lifecycle methods. These are planned in a future hooks update.
Aside from those, every other feature of classical components can be rewritten in functional components that use hooks.
Classical components allow inheritance, but I personally don't consider component inheritance as part of the list of classical component features because it has been strongly advised against since the beginning of React, as it goes against the design pattern React was built to accomplish.
Overall, after a few more updates to the hook feature, all classical components will be entirely rewritable as functional components that use hooks.
You will need classes if you want inheritance, or want a component with common functionalities and extend it as needed. Other wise hooks provide a better and cleaner, easy to read, faster way to do almost all class functions.
Check this To-Do App with out using any classes.

VueJs 2 with Vuex vs React with Redux

I've spent the past few days looking at VueJs 2 with Vuex and i really like it.
Having only had a brief introduction to React, I've found vue js 2 has been easier to pick up.
React seems to be growing in popularity, but I can't see the benefits of React over Vue 2.
Both are component based frameworks with routing and state management tools.
So can someone explain which are the main differences between those frameworks?
This is an opinionated and subjective question. And it often starts holy-wars than really answering anything and thus it is not really suitable for StackOverflow. However, I will try to answer this in an objective manner as possible. (Note: I am purely comparing Vue with React and deliberately avoiding Vuex vs Redux)
Why Vue.js?
It is designed to be an approachable framework. It is suitable for beginners and advanced users alike. When you are starting with Vue.js, it is as simple as adding a script tag to your page. For the advanced developer, the possibilities are endless. You can start with any sophisticated build tools - TypeScript, Babel, Webpack, etc.
Vue.js is developed much after Angular and React. It has learned from both and managed to pick many best things from them into Vue. For a beginner, Angular's idea of components, services, dependency injection, bootstrapping application, etc can feel overwhelming. Same is applicable to React; JSX can feel odd (Even after years, I still find it weird.). Now, Vue.js is a cross-path. You can use angular like templates or you have the freedom to choose React like JSX.
Vue.js reactivity is very well abstracted. With Angular (digest cycle in v1 and zones in v2) or React, it is bit different. It takes time to learn these concepts.
There are tons of other reasons why Vue.js should be your choice. Sometime back, I had written an article explaining why Vue.js:
https://blog.webf.zone/vue-js-answering-the-why-after-15-months-62db797f75cc
Why React?
React is a pioneering library (It is not a framework) just like Angular. It introduced the ideas of uni-directional architecture, virtual-dom, components (stateful and stateless), etc.
React Native is another reason why you may want to consider React. It allows you to take the same code that you wrote for Web and build native mobile applications. Now solutions do exist in the Vue.js world. But definitely not as mature as React Native.
Functional programming: No way React is a library based on functional programming. But doing React right way means you need to use immutability, explicit state management and all these allied concepts stemming from functional world.
Redux: Redux is the darling of React world. It has unlocked wonderful architectural patterns for front-end world like time-travel debugging, explicit side-effects, functional components, etc.
Innovation: React has some crazy ideas like Relay, Next.js (Vue.js has Nuxt.js). I also heard about some Drap-n-drop editor for React; first class TypeScript and Flow support (You just cannot get TypeScript + Vue.js + JSX working together even in 2018).
Why not React?
Using only React is not enough. Very soon, you will end up with using Redux, Redux middleware, Immutable.js, etc. Doing all of that at once can be intimidating.
Redux. It is wonderful but it is verbose.
Most important: Using React without any sophisticated build system is cumbersome. To do anything serious, you will need Babel, Webpack, etc.
Again, which one is better?
There is no better solution. I will choose Vue.js if I need to accommodate a vast array of developers (beginners-advanced). I will choose React if my team is versed with all the extra overload that comes with React and team loves everything JavaScript approach to web development (Even CSS is JS).
Finally, there is one another angle to it. Programming in React needs discipline and hence, there is a good chance that you will find it easier to bring homogeneity to your codebase. With Vue.js, there is often more than one solution to a problem. That makes it good and bad at the same time.
You will not go wrong with either of them.

Resources