React Multiple Higher-Order Components - javascript

I'm just discovering the amazing benefits of using HOC in my react projects.
My question is there any performance hit for calling multiple HOC functions on a component?
Example
export default withState(withLabel(withTheme(MyComponent)))
This will of course only render one component, however looking at my react dev tools i can see the outputted HOC components three levels deep. Is this something to be wary of or is there a better approach to calling multiple HOC on a component?

Your syntax is equivalent to doing:
<StateProvider>
<LabelProvider>
<ThemeProvider>
<MyComponent />
</ThemeProvider>
</LabelProvider>
</StateProvider>
The performance hit will come from how these HOC are implemented. You would probably have to look at each of them.
Example:
Theme Provider HOCs usually store a bunch of colors and variables in the React context. So using only one at the very root of your App is enough.
One could imagine that your LabelProvider simply adds an extra span before your component, in which case there is little to worry about
StateProviders like redux usually inject props in the component just below them so you don't really have a choice but to use them whenever you need state objects.
In conclusion, there are no hard rules. Your main focus should be on understanding what these HOC do and to try to limit unnecessary re-renders of your app.

I wouldn't use that. It's complicated to understand where the props come from, when you are looking at your MyComponent component. There are much more downsides using this pattern. Anyway if you decided to use HOCs use it in a right way e.g.
const withDetails = Component => {
const C = props => {
// do something
}
// assign display & wrapped names - easier to debug
C.displayName = `withRouter(${Component.displayName))`
C.WrappedComponent = Component;
return C;
}
Instead of using HOCs i suggest looking at render props react pattern. It's well explained in a Use a Render Prop! article by Michael Jackson (react-router creator).
Hope it makes sense.

Related

React pure component with hooks and state

I'm struggling about what may be a good way to implement components in React with a good coding pattern.
Normally I know the idea of presentational and container components: the presentational only shows html and receive everything from props (data and callbacks); the container orchestrate the presentationals retrieving and mutating data and passing it to them by props.
Now I'm using redux with redux toolkit and rtk query, with hooks.
Following that approach, the container component should be the only one allowed to useSelector and useDispatch and useQuery. But I find a lot easier and cleaner allowing the presentationals to select and fetch and dispatch what they really need, instead of making a giant container component which manage all the data for its children with a huge list of state and fetch access. This is true especially for lists, where it is a lot easier and cleaner just letting each child to retrieve its own data (fetched or from state), or for deeply nested presentationals.
However I'm mixing up container components with fake presentationals which anyway retrieve something when it is easier and true presentationals maybe for general and totally reusable components. Also the components tree is very messy (like container->fake presentational->container->fake presentational->true presentational->true presentational ...).
At the end I feel like I don't have good rules and the code is messed up.
Are container and presentation components still a good coding style which follows a best practice pattern but in the world of hooks and redux?
The React Container Pattern advocated by Dan Abramov has for all intents and purposes been deprecated since the introduction of React hooks in 2018.
See Dan's blog entry Presentational and Container Components from 2015.
His update from 2019:
Update from 2019: I wrote this article a long time ago and my views
have since evolved. In particular, I don’t suggest splitting your
components like this anymore. If you find it natural in your codebase,
this pattern can be handy. But I’ve seen it enforced without any
necessity and with almost dogmatic fervor far too many times. The main
reason I found it useful was because it let me separate complex
stateful logic from other aspects of the component. Hooks let me do
the same thing without an arbitrary division. This text is left intact
for historical reasons but don’t take it too seriously.
With the advent of React hooks the distinction between "smart" and "dumb" components, and "container" and "presentational" components, was all but eliminated.
The common pattern and "best practice" now is to write React Function components and just use the React hooks. In the case of using Redux and React-Redux, the useDispatch and useSelector hooks instead of the connect Higher Order Component. I've not gone out of my way to write a React Class component or split my code between "presentation" and "container" since the advent of React hooks.
My rule of thumb is to do it all in one component. Then as you create more and more components you'll see patterns start to emerge. So instead of copying and pasting code from component to component you can make a presentational component that takes in props for what to render. Some of those props can even be what to do when a button is clicked or a box is checked.
Overall your presentational components will end up resembling something like one of the various react js ui frameworks out there such as https://mui.com/

Rendering query string variables in React [duplicate]

After spending some time learning React I understand the difference between the two main paradigms of creating components.
My question is when should I use which one and why? What are the benefits/tradeoffs of one over the other?
ES6 classes:
import React, { Component } from 'react';
export class MyComponent extends Component {
render() {
return (
<div></div>
);
}
}
Functional:
const MyComponent = (props) => {
return (
<div></div>
);
}
I’m thinking functional whenever there is no state to be manipulated by that component, but is that it?
I’m guessing if I use any life cycle methods, it might be best to go with a class based component.
New Answer: Much of the below was true, until the introduction of React Hooks.
componentDidUpdate can be replicated with useEffect(fn), where fn is the function to run upon rerendering.
componentDidMount methods can be replicated with useEffect(fn, []), where fn is the function to run upon rerendering, and [] is an array of objects for which the component will rerender, if and only if at least one has changed value since the previous render. As there are none, useEffect() runs once, on first mount.
state can be replicated with useState(), whose return value can be destructured to a reference of the state and a function that can set the state (i.e., const [state, setState] = useState(initState)). An example might explain this more clearly:
const Counter = () => {
const [count, setCount] = useState(0)
const increment = () => {
setCount(count + 1);
}
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
</div>
)
}
default export Counter
As a small aside, I have heard a number of people discussing not using functional components for the performance reasons, specifically that
"Event handling functions are redefined per render in functional components"
Whilst true, please consider if your components are really rendering at such a speed or volume that this would be worth concern.
If they are, you can prevent redefining functions using useCallback and useMemo hooks. However, bear in mind that this may make your code (microscopically) worse in performance.
But honestly, I have never heard of redefining functions being a bottleneck in React apps. Premature optimisations are the root of all evil - worry about this when it's a problem.
Old Answer: You have the right idea. Go with functional if your component doesn't do much more than take in some props and render. You can think of these as pure functions because they will always render and behave the same, given the same props. Also, they don't care about lifecycle methods or have their own internal state.
Because they're lightweight, writing these simple components as functional components is pretty standard.
If your components need more functionality, like keeping state, use classes instead.
More info: https://facebook.github.io/react/docs/reusable-components.html#es6-classes
UPDATE Jan 2023
TLDR; Functions are the best way to create components. React.Component is a legacy API.
"We recommend to define components as functions instead of classes."
"Class components are still supported by React, but we don’t recommend using them in new code."
https://beta.reactjs.org/reference/react/Component
UPDATE March 2019
Building on what was stated in my original answer:
Are there any fundamental differences between React functions and
classes at all? Of course, there are — in the mental model.
https://overreacted.io/how-are-function-components-different-from-classes/
UPDATE Feb 2019:
With the introduction of React hooks, it seems as though the React teams wants us to use functional components whenever possible (which better follows JavaScript's functional nature).
Their motivation:
It’s hard to reuse stateful logic between components.
Complex components become hard to understand.
Classes confuse both people and machines.
A functional component with hooks can do almost everything a class component can do, without any of the draw backs mentions above.
I recommend using them as soon as you are able.
Original Answer
Functional components aren't any more lightweight than class based components, "they perform exactly as classes." - https://github.com/facebook/react/issues/5677#issuecomment-241190513
The above link is a little dated, but React 16.7.0's documentation says
that functional and class components:
are equivalent from React’s point of view
https://reactjs.org/docs/components-and-props.html#stateless-functions
There is essentially no difference between a functional component and a class component that just implements the render method, other than the syntax.
In the future (quoting the above link):
we [React] might add such optimizations
If you're trying to boost performance by eliminating unnecessary renders, both approaches provide support. memo for functional components and PureComponent for classes.
https://reactjs.org/docs/react-api.html#reactmemo
https://reactjs.org/docs/react-api.html#reactpurecomponent
It's really up to you. If you want less boilerplate, go functional. If you love functional programming and don't like classes, go functional. If you want consistency between all components in your codebase, go with classes. If you're tired of refactoring from functional to class based components when you need something like state, go with classes.
Always try to use stateless functions (functional components) whenever possible. There are scenarios where you'll need to use a regular React class:
The component needs to maintain state
The component is re-rendering too much and you need to control that via shouldComponentUpdate
You need a container component
UPDATE
There's now a React class called PureComponent that you can extend (instead of Component) which implements its own shouldComponentUpdate that takes care of shallow props comparison for you. Read more
As of React 17 the term Stateless Functional components is misleading and should be avoided (React.SFC deprecated, Dan Abramov on React.SFC), they can have a state, they can have hooks (that act as the lifecycle methods) as well, they more or less overlap with class components
Class based components
state
lifecycle methods
memoization with React.PureComponent
Functional components:
state (useState, useReducer hooks)
lifecycle methods (via the useEffect, useLayoutEffect hooks)
memoization via the memo HOC
Why i prefer Funtional components
React provide the useEffect hook which is a very clear and concise way to combine the componentDidMount, componentDidUpdate and componentWillUnmount lifecycle methods
With hooks you can extract logic that can be easily shared across components and testable
less confusion about the scoping
React motivation on why using hooks (i.e. functional components).
I have used functional components for heavily used application which is in production. There is only one time I used class components for "Error Boundaries" because there is no alternative "Error Boundaries" in functional components.
I used "class component" literally only one time.
Forms are easier with functional, because you can reuse form input fields and you can break them apart with React display conditionals.
Classes are one big component that can't be broken down or reused. They are better for function-heavy components, like a component that performs an algorithm in a pop-up module or something.
Best practice is reusability with functional components and then use small functional components to assemble complete sections, ex.- form input fields imported into a file for a React form.
Another best practice is to not nest components in the process of doing this.
Class-based components offer a more structured and organized way to define and implement a component, and they provide additional features and capabilities, such as the ability to use local state and lifecycle methods. This can make them a good choice for creating complex components that require a lot of logic and functionality.
On the other hand, functional components are simpler and easier to work with, and they can be more performant because they are more lightweight. They are also easier to test and debug, because they are pure functions that don't have side effects. This makes them a good choice for creating simple components that don't require a lot of logic or state management.

Best way to pass props down through many components

Let's say that I'm fetching some images from an API in the App component.
Then I want to pass it to the component responsible to rendering images. But this component is not a direct child to the App component. It is the child of a direct child of App component.
Here's how I would pass the images array down to the image component, but I feel like it might not be the best approach.
But what would happen if this hierarchy gets more complex - even just by one more component:
Intuitively, it might not be the best thing.
So, what would be the best way to pass the images array down to the image component, if there are many other children between them?
The problem is usually called Prop Drilling in the React world: https://kentcdodds.com/blog/prop-drilling
A few options:
Passing props may not be that bad. If the app is small, is a very modular -and easy to unit test- option . You can reduce the verbosity by using prop spread: <Comp {...props} /> and by keeping your component interfaces similar. (many people dislike prop spreading as you can unintentionally pass unsupported props, but if you use TypeScript the compiler will catch that).
You can use a React Context: https://reactjs.org/docs/context.html (as other mention in the comments). However, keep an eye on how your context objects are defined (keep them small). React will re-render all the childs using the context when the value changes, is not smart enough to automatically detect changes at the property level. Frameworks like Redux or Zustand use other mechanisms to allow a granular control of the shared state (you'll see examples of a useSelector hook).
You can also take a look to a state management framework (Zustand is my favorite, but Redux is more popular). However, it may be an overkill for small things.
My personal choice is to start with prop drilling, it's easier to modularize and unit test. Then you can think on your app in layers: upper layers depend on a context (or a state framework), and lower layers receive properties. That helps when you want to refactor and move reusable components to other projects.

Is this good practice for react functional components?

Recently I've been writing more and more of my react components in a functional style, since most of them don't need the lifecycle functions or state. Inside my components (which are, again, just functions) I define helper functions - onClick functions and all that jazz. But now I'm thinking if this is good practice? Since the function is called for each render, does it recreate all the internal functions? I'm curious about memory loss and whether I'm doing this wrong.... An example of a component:
import React from 'react';
import { connect } from 'react-redux';
import ProductSearch from '../Plan/components/ProductSearch';
const BlockedProducts = (props) => {
const onSelectProduct = (product_key) => {
console.log(product_key);
};
return (
<ProductSearch onSelectProduct={ onSelectProduct } />
);
};
export default connect()(BlockedProducts);
Yes, there will definitely be some performance hit by virtue of the fact that you're declaring a function every single time you render BlockedProducts. How efficiently that gets cleaned up from garbage collection I don't know, but it seems best not to press your luck.
Functional components in React are really meant to be completely stateless and not "do" anything except be presentational. The ideal functional component just returns some JSX/HTML to render, no bells and whistles. In my opinion, a functional component should ONLY have a return, and as soon as you start adding interior functions it should be upgraded to a full fledged React class.
You could move the onSelectProduct declaration from BlockedProducts scope by putting it above component. It will make a closure to component's scope, because BlockedProducts declaration will be in the same scope with onSelectProduct.
I don't think that it will cause some perf issues. I do agree with #jered - a stateless components should be as simple as possible, so try to don't make any business logic there.
I have came to the same question recently. https://github.com/yannickcr/eslint-plugin-react/issues/357 Daniel discusses that this approach will increase GC workload, so he uses class components instead.
I would argue that first of all class components are for handling lifecycle and state and they also have impact to performance by creating backing bean, that suppose to deal with lifecycles and state.
Therefore I would use functional class instead and create class components when real performance issues will arise
Btw, 10 months have passed, I am curious which approach you have finally sticked with?

React with Redux? What about the 'context' issue?

I normally post code related stuff on Stack, but this is more a question about what the general thoughts of the community are.
There seems to be a lot of people advocating the use Redux with React to manage data/state, but while reading and learning both I've come across something that doesn't quite look right.
Redux
At the bottom of this page: http://redux.js.org/docs/basics/UsageWithReact.html (Passing the Store) it recommends using the "Magic" of React 'Context'.
One option would be to pass it as a prop to every container component. However it gets tedious, as you have to wire store even through presentational components just because they happen to render a container deep in the component tree.
The option we recommend is to use a special React Redux component called to magically make the store available to all container components...
React
On the React Context page (https://facebook.github.io/react/docs/context.html) it has a warning at the top:
Context is an advanced and experimental feature. The API is likely to change in future releases.
Then at the bottom:
Just as global variables are best avoided when writing clear code, you should avoid using context in most cases...
Do not use context to pass your model data through components. Threading your data through the tree explicitly is much easier to understand...
So...
Redux recommends using the React 'Context' feature rather than passing the store along down to each component via 'props'. While React recommends the opposite.
Also, it seems that Dan Abramov (the creator of Redux) now works for Facebook (the creator of React), just to confuse me more.
Am I reading all this right..?
What is the general current consensus on this issue..?
Context is an advanced feature and is subject to change. In some cases its conveniences outweigh its downsides so some libraries like React Redux and React Router choose to rely on it despite the experimental nature.
The important part here is the word libraries. If context changes its behavior, we as library authors will need to adjust. However, as long as the library doesn’t ask you to directly use the context API, you as the user shouldn’t have to worry about changes to it.
React Redux uses context internally but it doesn’t expose this fact in the public API. So you should feel much safer using context via React Redux than directly because if it changes, the burden of updating the code will be on React Redux and not you.
Ultimately React Redux still supports always passing store as a prop so if you want to completely avoid context, you have that choice. However I would say this is impractical.
TLDR: Avoid using context directly unless you really know what you are doing. Using a library that happens to rely on context internally is relatively safe.
I don't know about others, but I prefer using react-redux's connect decorator to wrap my components so that only the props from the store I need are passed into my component. This justifies the use of context in a sense because I am not consuming it (and I know, as a rule, any code that I am in charge of will not consume it).
When I test my components, I test the non-wrapped component. Because react-redux only passed the props I needed on that component, I now know exactly what props I need when I'm writing the tests.
I suppose the point is, I don't ever see the word context in my code, I don't consume it, so to a certain degree, it doesn't affect me! This doesn't say anything about Facebook's "experimental" warning.. If context disappeared, I'd be just as screwed as everyone else until Redux was updated.
There's an npm module that makes it really easy to add redux to the react context
https://github.com/jamrizzi/redux-context-provider
https://www.npmjs.com/package/redux-context-provider
import React, { Component } from 'react';
import ReduxContextProvider from 'redux-context-provider';
import createStore from './createStore';
import actions from './actions';
import Routes from './routes';
export default class App extends Component {
render() {
return (
<ReduxContextProvider store={store} actions={actions}>
<Routes />
</ReduxContextProvider>
);
}
}
React ships with all the features you need to handle your state without a single additional library. Most of your application's states should not be global as they live just fine in a useState or useReducer or custom hook next to your components.
So before you dive into the world of advanced state management (e.g. Redux), consider using the tools React ships with out of the box.
If you are interested in learning a bit more about this, I'd recommend this article by Andy Fernandez, which dives into the details on Redux: Context API vs Redux

Categories

Resources