Volto - Creating Views: When to use Class Components vs Functional Components

I've noted that some views are implemented as Class Components and some as Functional components. I'm not sure when to use one approach over the other (I know functional components are stateless, so that's probably a hint).
For example the FaqView code in Mastering Plone
is declared as a class component like this:

class FaqView extends Component { ....

While FullView in the Volto training document
is declared as a functional component like this:

const FullView = ({ content }) => (

/me goes to read more about this stuff...

The following article seems to suggest that functional components are the right way to go MOST of the time.

The future React documentation on Quick Start seems to favour the functional approach.

Most of Volto's older code is class based and the newer is function based. They usually have the same capabilities on their own, but only functional components can use hooks (some third party libraries only provide hooks as API, for example). In any case, writing a functional component feels a lot less "ceremonial". You only need to write one declaration: the function, instead of declaring a class, a constructor and a render method. It's just less to write, and personally I don't have snippets in my editor, so I favor whatever is faster to write.

With a bit of experience in writing functional components, you'll soon arrive at an important reusability pattern in React and you'll write your first hook. A hook is just another function, but it has the ability to call other hooks. So you can do useEffect, useState, inside a hook, do async network requests, etc. They're the basic building blocks to making your code cleaner and easier to reuse and think about.

Another basic building block is the "HOC", the "higher order component", which is similar to a Python decorator. You wrap a component with it and because of React's component composition system, you can write a new component that "enhances" the original component. You can read the value of the props that the original component would receive and you can inject new values.

But in the end, don't stress too much. Have fun with this, do whatever it feels best. It's not that difficult to convert between classes and functional, if you really feel like, at a later point.

1 Like

I'd love to see a solid example of the best practices moving forward for function-based and HOC.

My current goal is to implement a function-based user profile component (to mimic classic Plone's /author view), with the following route:

 {
        path: '/author/:id',
        component: AuthorView,
        exact: true,
      }

Unfortunately, the examples I'm finding in the Volto code are class-based.
E.g. https://github.com/plone/volto/blob/master/src/components/theme/PasswordReset/PasswordReset.jsx

found a good video on converting Class Components to Functional Components and introducing useState

The Search block is all functional components, hooks and HOCs.

Here's a nice simple example of using a HOC as a "behavior": when the component is rendered, fetch some data and inject it into the component: volto/withQueryString.jsx at master · plone/volto · GitHub

And here's a really simple hook to illustrate the fact that hooks are just functions that can call other hooks.