Is it good practice to store whole React Components in the component state or redux state? Yes, it's optional as we could store a string in the state and render the component conditionally but in some cases, it is simpler to just store the component in the state.
For example,
const [ components ] = useState([
{ id: 1, component: <Login />, title: `Login` },
{ id: 2, component: <Register />, title: `Register` },
])
But components can be large and I was wondering if that makes any difference. Is this a bad practice?
I would not recommend it. But not for the reason that those instances would somehow add too much size to the state (which I don't think they would).
The strongest argument in my opinion is: the instantiated components are stale; their properties will only have those values that were assigned when they were instantiated. That might or might not lead to problems down the road. It definitely introduces an additional risc for bugs in your app. Normally all components are created and parameterized when a render function is run; receiving the newest property values; this will not be the case for those that are kept in state.
Instantiating a component is usually not an expensive operation; and it does not imply a corresponding DOM update, as react uses a diffing mechanism to decide which parts of the DOM needs updating.
All the use cases I can think of -where storing instantiated components in state might be considered- can be solved in a more react idiomatic way:
Conditionally rendered elements:
const [showPrompt, setShowPrompt] = useState(false);
// ...
<div>{showPrompt && <ConfirmationPrompt />}</div>;
or
const MyComponent = ({showPrompt}) => {
// ...
<div>
{ showPrompt && <ConfirmationPrompt /> }
</div>
Optimizing the number of times a new react element is created:
If you have reason to think your render function is quite heavy and you want to reduce the number of times it is run, you can use the useMemo hook (to memoize calculation results within you render function) or you can wrap your whole component in React.memo() so it is only re-rendered when the props change.
const primeNumbers = useMemo(() => calculatePrimeNumbers(limit), [limit]);
const MyComponent = React.memo((props) => {
/* render using props */
});
My original answer was caustic. I edited it, keeping the reasoning, but removing the unhelpful parts.