When to use stateless and statefull components in ReactJS after Hooks changes? - reactjs

So, i know the difference between the two but after hooks i'm kinda confused about when i should use stateless and when use statefull.
When i was learning the basics of React i was told that stateless is the "dumb" function and statefull is "smart". And that i should use stateless in simple things, because props are imutable and also use more than statefull. I dont really know the difference with Hooks changes in 16.8.
I know that we can use setState now but i dont understand it totally.

This is a great question, and one that I think people will have trouble with for a while. The way I see it, the term "stateless" has been dropped from regular component verbiage and they are just called "functional components".
The concept of "stateless" is still very important though, because it involves no inner state that does not mimic its props. As you said, they are dumb. Generally, if a component can be stateless, it will be more performant. Components that are rendered in loops with a high count do much better with this type of structure. On the other hand, don't stress too much about performance until you're hitting bottlenecks, which shouldn't happen until you've got thousands (or more) of components rendering at once.
To address hooks- they allow you to "hook" into the state and lifecycle of a component. As you will see in the docs, they do not offer more functionality, but a simpler API. This leads to cleaner code and more reusable custom hooks.
If you are dabbling with hooks, maybe try it on some new components you need to build. I've found it to be fun and simplifies my code considerably.
As a final answer, I would say that the concepts of "stateful" and "stateless" components is the same. Only the API that allows you to utilize state has been changed.

Your 'dumb' components should remaing dumb.
Your 'smart' components, can take advantage of hooks to make them 'dumb' with a hint of smart.
Imagine a component where you have to make it 'smart' because there is a toggle in it.
With the old way, you would create a component that has State.
With hooks, you can create a dumb functional component, that just happens to use the hook useToggle.
This keeps your code simple and concise, while at the same time keeping the same functionality you used to have building smart components.

Hooks are just another means to use state (and other functionality) in a so-called "smart", functional, component. That said, their existence doesn't change the answer to this question (of which, there are many).
One example of an appropriate use of state is when you have a component that will render different output based on some sort of change to the component after the initial render. More specifically, if you have a component that needs to make a network call to fetch some data for display, you could use state to keep track of the initial non-existence of that data and update it when the network call returns using setState.
In my experience, as a general pattern, you should use state for things that change and props for things that don't.

I think, the question is actually simple, when do we use the state hook in react? The answer is, if you write a function component and realize you need to add some state to it, now you can use a state hook inside that existing function component. Previously you had to convert it to a class component.
Then why don't we use the class component from the beginning instead of function component? Because when it was first introduced, the recommended pattern for react developers was to use as many stateless components as possible, in other words as many function component.
And in my personal opinion, the function component is neater and easier to use, maybe even more suitable with the reusable component concept. So then, yeah, now we can expand the use of the function component even more.
Hope it helps

Related

Are there any relevant use case for React Render Props and HOC with functional components?

I know it's possible to use RRP and HOC patterns with functional components, my question actually is, are there any point on doing that? Making some researches I read React/Custom Hooks can essentially handle what render props did in the past with Class Components. The fact is there is not very much information about these patterns in relation to Functional Components, almost every example out there use Class Components, so I was wondering if there's a relevant place to it in Functional Composition.
This is how I would put it: In most of the cases, you would use hooks; in some specific situations you may use, higher-order components.
From a control perspective, hooks provide more flexibility for the user of the code. It means there is a possibility that they could be used in not-intended way. But I would call it a theoretical possibility.
If your reusable logic has JSX as well as some custom logic, may be providing higher-order component or, even render props, makes more sense. Of course this means, that you should have extremely well defined lifecycle for your component and you would not like to provide complete control to the user.
An example would be react-router which is combination of both hooks and render props where applicable.

Is it fine if useContext has many useState in React

I am working using useContext in React. Today, I recognized that I am using too many useState in useContext. I was looking for the answer, but I could not find it.
I know it is a silly question, but please answer my question if possible.
Thank you.
Thank you for the answers to my question. So, I understand that if there will be many states in useContext, it is a good way to use useRedux.
This is my opinion. I think there is no such thing as too much as long as your states are relevant with what you are doing. It depends on what is your purpose when using the createContext. But make sure to organize them well so that they are still modular and not mixed with other context of states.
For me, I draw a simple borderline where if I'm only making some one-off reusable components that need control from far away (e.g. Dialog which can be toggled by deeply nested button), then I should create a context that has just enough states for that component. Whereas if I want to store some states which I want to access from multiple places, especially if it is related to business logic, then I prefer to use Redux instead.
I think useContext and useState are different functions:
useContext: This is a hook that returns values from the context that has been kept. Any change in values causes the react component where this hook is placed to rerender.
useState: a hook that declares the react component's state.
I think I understand what you mean when you say you declare many states in the context. Some best practices you need to consider are:
Using useReducer hook to group & manage the change of states. It makes it easier to control the changing of states. It is obvious that the state shifts with each individual action.
You need to review the total state that is declared. Only keep states that need to be shared in that context.
Refer: read more in react js docs about context api & declare a state in react component.

When should I use observer in mobx-react?

I'm doing on migration all of my class component to functional component using mobx-react
I wonder all of my components should wrapped by observer or not.
I guess there might be three scenarios.
observable states are being called and used.
observable states are been passed into props
purely stateless component.
let's say all of three components above are functional component.
Should I wrap all the components above with observer of mobx-react?
cf) Is there any articles or benchmarking compares to #observer decorators of mobx ?
Basically this https://mobx.js.org/refguide/observer-component.html#when-to-apply-observer and https://mobx.js.org/best/pitfalls.html#use-observer-on-all-components-that-render-observable-s
You usually wrap everything in observer, exception might be components which only render primitives or something like this, but it is tedious to track it so usually you just wrap all of them.
Mobx's guideline is to put it on any component that reads observable data:
https://mobx.js.org/react-integration.html#always-read-observables-inside-observer-components
If I understood the question correctly, the right answer is on the documentation Mobx site:
You might be wondering, when do I apply observer?
You might be wondering, when do I apply observer? The rule of thumb is: apply observer to all components that read observable data.
observer only enhances the component you are decorating, not the components called by it. So usually all your components should be wrapped by observer. Don't worry, this is not inefficient. On the contrary, more observer components make rendering more efficient as updates become more fine-grained.
p.s.:
there are broken links in first reply,

Why use useState over this.state?

I have been learning React hooks lately and I am currently facing useState. I know this is a way to use state in functional components but I wonder what the real benefits are above using a React.PureComponent with this.state?
Is it really bad practice now to use a PureComponent instead of useState or useEffect? Does this make the app "faster"?
I know this question sounds dumb because useState is the new kid on the block but I just need a valid reason to refactor my old components into this new pattern?
Edit: I've been using hooks for a while now and like them a lot (changed my opinion), however it increases the learning curve and there are pitfalls:
Good stuff:
Not wrapping your component in Higher Order Components (looks cleaner and sometimes order of HOCs can cause issues)
Composability and re-use becomes easy - splitting code out to custom hooks is second nature. Also reduces argument for adding other abstraction concepts around state management, data fetching, utilities since hooks can do it all.
No confusion around this (easily avoided with arrow functions in classes tbh)
Some components come out cleaner and terser (but some especially with lots of event listeners can turn into a hot mess without careful architecture and knowledge of how to make the best use of hooks)
Some libraries are hook compatible or hook focused only these days (not a "good" thing but an argument for use)
Bad stuff:
Larger API surface area/knowledge - memo, useCallback, useMemo, useRef, useEffect, useLayoutEffect, useState etc. Ask a beginner how to debounce a callback - suddenly it's a hard problem.
Functions can become unmanageable since hooks have to all be called in them in the same order (note: you can make your own hook with more hooks inside to split things up)
Trading confusion around this for much more problems such as:
Infinite loops when you both read and write to a variable in a memoized hook
Stale data if you didn't list dependencies, also if you didn't then you can prevent garbage collection on any trapped references.
Getting into a dependency hell to avoid stale references (wrapping stuff in useCallback, then "tunnelling" some of the variables in with useRef etc)
Performance degradation since hooks are slower to execute and create, non-hook functions are created every render and also will break purity checks of children, even functions in hooks such as useRef (and I believe useCallback) are quietly created and discarded every render in favour of the first one created.
Testing hooks nested in a function is harder/more complex than testing class methods
Side note: Solid framework has a better implementation of hooks which don't require dependencies
TL&DR: There is no need to refactor all old components.
useState and others react hooks introduce a new way to implement your components. They can be helpful as they simplify code reusability. You can move your specific logic to a custom hook and use it in several components. Custom hooks can call useState and they don't have any possibility to damage state from other useState calls. It allows you to split component logic more wisely.
So there are 2 main profits of using useState: code reusability and code splitting.
When it's better to refactor old components?
Let's say, you have 3-4 legacy components, which make similar things, but it's complicated to reuse code. You can rewrite such components to hooks, move all common logic to custom hook and reuse this hook in all of these components.
Also, if you have any additional questions you can take a look to this https://reactjs.org/docs/hooks-intro.html article
And one important thing: PureComponent equivalent in "functional component world" is to wrap your function with React.memo
useState, this.state and PureComponent are different terms and need not be confused together. As you understand useState is a way of handling state in a functional component whereas you use this.state for a class component.
As far as PureComponent is concerned, it used to optimize renders and you can use React.memo for the same purpose for a functional component.
Also as far as refactoring is concerned, there is no need to do that since Class components will continue to exist and react community recommends you to not refactor the previous code.
I recommend for you to watch React Today and Tomorrow and 90% Cleaner React With Hooks
also, you can read Introducing Hooks
according to using pureComponent, pureComponent is similar to Component which is Class, check classes confuse both people and machines section to understand why functions are better than classes.

How best to send Immutable.JS list into a stateless React component?

I'm using Redux, Immutable.JS, and React. I want to pass an Immutable.JS list into my stateless React component. This component maps through the list and renders a child per item in the list.
Example:
function Cats(props) {
function Cat(p) {
return <li key={p.id}>p.name</li>;
}
return <ul>{props.cats.map(Cat)</ul>;
}
The {p.id} part breaks, because props.cats is an Immutable.JS list of maps, so I'd have to update my React component to say {p.get('id')} instead.
I'd be okay to do this, but are there better ways for a stateless React component to consume a list without having to know that it's an Immutable.JS list? This usage violates the best practice in the Redux + Immutable.JS + React best practice, "Use Immutable.JS everywhere except your dumb components". 1
I'm certain other people have dealt with this problem and I don't want to reinvent the wheel.
Can relate with your pain, I have documented this here - What are disadvantages to using immutable state in React?.
For Redux
You can use mapStateToProps to convert immutables into normal JS (state.toJSON()). So the dumb (don't like that term) components should be abstracted from the actual structure of your state.
Otherwise
This is an issue anywhere you want abstraction between your state library and your views. One way I have been able to isolate this to some extent is to use (lenses)[https://medium.com/#drboolean/lenses-with-immutable-js-9bda85674780]. If they seem too complicated, you can make a get([key path], source) method and send that in props to your components and use it to fetch the value. This at least provides some abstraction.
You are not wrong.
If using ImmutableJs what you should do is p.get('id') the other way would be something like props.cats.map(elem => <Cat id={elem.get('id')} key={elem.get('id')}/>)
or IMHOP less elegant props.cats.map(elem=>elem.toJs()).map(Cat) but its just different ways of doing the same thing.
Hope it helps

Resources