Reputation: 389
Until now we were used to Flux flow where data entered into the component through props. So you could look at the Props signature and see what is the component requirements.
Hooks are an amazing feature, but as we transition to them I find that they provide another entrance for dependencies which is harder to manage since you have to look at the actual component code to see it.
Of course, we can use Hooks only in container components, but I feel that some of their main selling points are their ability to reduce nesting and HOC.
What are the best practices (currently) for deciding which component should use a hook and which should use render props?
Upvotes: 17
Views: 6391
Reputation: 102407
HOC is some kind of AOP, AOP can solve cross-cutting concerns.
React Hooks is not AOP, from Rules of Hooks, hooks can only be used in the following ways:
Both of them follow the separation of concerns design pattern.
react hooks provide a component lifecycle hook useEffect
, so you can create reused custom hooks based on the component lifecycle hook useEffect
and other built-in hooks.
HOC is more flexible, from the doc:
You may have noticed similarities between HOCs and a pattern called container components. Container components are part of a strategy of separating responsibility between high-level and low-level concerns. Containers manage things like subscriptions and state, and pass props to components that handle things like rendering UI. HOCs use containers as part of their implementation. You can think of HOCs as parameterized container component definitions.
And let's use an example to explain cross-cutting concerns.
If you have a reused react custom hook called useGetEnumsQuery()
, and you have ten components will use it. You need to import and call the hook ten times.
Now, you create a HOC named withEnums()
you can call the useGetEnumsQuery()
hook in the HOC once and pass the enums to the wrapped components via props.
HOC is react component as well. If we put too much code logic in HOC, it doesn't follow the separation of concerns design pattern. So we can create several react custom hooks to encapsulate different logic.
So in my opinion, If there are more than 3 components using the same logic, I will use HOC + react custom hook.
HOC helps me solve the repeated import and call hook in each component issue mentioned above. React custom hook helps me separate components and logic.
HOC and react hooks are not conflicting, they should be used in combination.
An example:
import React, { useCallback, useMemo, useState } from 'react';
const MaskContext = React.createContext({ visible: false, show: () => {}, hide: () => {} });
// Abstract a "mask" view model using a react custom hook.
const useMask = () => {
const [state, setState] = useState(false);
const hide = useCallback(() => setState(false), [setState]);
const show = useCallback(() => setState(true), [setState]);
return useMemo(() => ({ visible: state, show, hide }), [state, show, hide]);
};
// HOC, pass the context value to the wrapped component without modifying it.
const WithMask = (WrappedComponent) => {
const mask = useMask();
return () => (
<MaskContext.Provider value={mask}>
<MaskContext.Consumer>{(value) => <WrappedComponent mask={value} />}</MaskContext.Consumer>
</MaskContext.Provider>
);
};
const MyComp = ({ mask }) => {
return <button onClick={mask.show}>click me!</button>;
};
const MyCompWithMask = WithMask(MyComp);
const App = () => {
return <MyCompWithMask />;
};
Upvotes: 1
Reputation: 678
One thing I see often is to use hooks with side effects in a component. That makes your component harder to test and is not a good use case for hooks imho.
For example you create a component with some custom const {data, loading, error} = useFetch(endpointUrl)
and then directly use it in the render part return <>{data.name}</>
of the same component.
This, for me, is still a use case for a HOC. Load the data in a HOC, provide it as properties to your still dump component. This way you can test the component easier and you still separate concerns.
Upvotes: 1
Reputation: 5081
Hooks and HOCs are different programmings models, and comparing them will seem to be as comparing oranges and apples.
TL;DR
As a rule of thumb, I use HOCs when I want a conditional rendering of components (if condition: render A, else render B), otherwise, I use hooks. That's only my opinion.
HOCs Pros
HOCs Cons
x
.HOCs Pro & Con both
Hooks Pros
Hooks Cons
Upvotes: 9
Reputation: 281834
And according to the React FAQs hooks can be used as an alternative to renderProps
and HOCs
, but can coexist with them
Often, render props and higher-order components render only a single child. We think Hooks are a simpler way to serve this use case. There is still a place for both patterns (for example, a virtual scroller component might have a renderItem prop, or a visual container component might have its own DOM structure). But in most cases, Hooks will be sufficient and can help reduce nesting in your tree.
Hooks allow stateful logic in functional components and would be similar to class components in React.
Hooks are harder to manage since you have to look at the actual component code to see it.
Not really, since you can pull out the custom logic that you have in your HOCs or renderProps in a custom hook and look for its implementation instead of understanding what actually is going on in the actual component.
Upvotes: 6