React js 18 Is it bad to have components that return null ?
Is it bad to have components that return null and are used just to subscribe to some events or for other purposes that do not include UI.I know that if there is just logic to be handled then use hooks but
-
Hooks work only with FC and
-
Hooks have to be called on the top of the component so they might not just be available on the top?
I have created one simple example here where I created a component just to "subscribe to some events" where it subscribes to events only if there is a user available and I am storing the user in redux I know this is not a real case because if I wrapped the <App/> with the provider in index.js rather than wrapping the content in App.js I could use the hook on the top but to be clear what I mean I did it that way because not always you can use that wrapper in the outermost component.
Is the GlobalSubscriber breaking any rules?
I don't think that you're breaking any rules per se, but if you're using a component just to add some logic to another component you should either use hooks instead (if using FCs) or use a HOC (higher-order component) that wraps around the component that needs the logic, rather than having to render the component by itself with no UI to return.
Perhaps the main reason hooks were created in the first place was to avoid having to use components to reuse logic. That said, if you need to use class components, read more about HOC since that is the way: https://reactjs.org/docs/higher-order-components.html
This is a great answer. Higher order components are basically identical to hooks in functionality and how confusing I found them was one of the reasons I was so happy to immediately move over to hooks/FC almost immediately after learning old react.
Yes thank you!! Hooks reuse logic, components are ui that may or may not have some logic. If there is some reusable piece of logic with no UI, it goes into a hook 100% of the time
JSX component can be added conditionally. Hooks cannot, by design.
If to choose between JSX with plain condition operators like &&
or custom hook with additional shouldIBeRun
boolean flag or even callback which returns true/false, I'm all for JSX and component which returns null
PS composition (JSX or HOC) is way more flexible than adding hook into a host component. Meanwhile for HOC we cannot wrap conditionally based on some component state(would require to lift state to parent so passing as props which not always optimal). JSX is most flexible here.
[upd] react router's <Navigate>
(former <Redirect>
) works exactly this way
Most of the answers here are right, that you want to avoid this pattern if possible, and use custom hooks, BUT, no one is really answering your question about the specific use case where:
You have a component, usually your root component, that needs to consume something that depends on a provider declared in that component. This happens commonly with redux, if you want to track user state (or something like that) at root and render something differently depending on that state.
To solve that problem with a hook instead of an empty component, you simply need to wrap everything inside the provider in it's own component, then access the data dependent on the provider in the sub-component. I altered your codesandbox with how I solve this problem.
It's bad practice.
While it's true that hooks only work with functional components, but that's what you should be using unless you're updating some older code base. Even if you have a good reason to use class components, they are methods for pretty much everything that hooks are used for.
Hooks have to be called on top of the component and that shouldn't be an issue with anything you may want to use them for. I'm not quite sure what you mean by hooks not being available on the top.
What I mean is that if I wanted to use it in the top in the App.jsx the useSelector() hook it wouldn't be available because the the Provider is wrapping the content inside the app, but if I created a component that returns nothing but just to use the useSelector hook and place it inside the App.jsx the hook would be available, I know that if I move the provider to index.js then it will be available in the App.jsx but what if you are using another wrapper that you can't just wrap the whole app