Why ReactJS components must act like pure functions? - reactjs

the documentation says
All React components must act like pure functions with respect to their props.
https://facebook.github.io/react/docs/components-and-props.html, but does not explain the real reason behind it, why is that?

A React component should be pure, this means the result of its render method should depend solely on the props and the state, and for the same properties and state render should give the same result.
If render is not pure, it means it can return different results for the same input, so React cannot tell which parts of the DOM need to be updated based on the changes to the component. This is critical as the performance of React depends of this. Why? That's a bit complex.
It is amazing to define the UI based on a state, and have the UI re-render itselfs every time any part of the state changes. But you can imagine doing a complete re-render of the entire DOM every time you change something would be painfully slow.
React solves this by checking the minimum ammount of changes needed o the DOM to reflect the new state. It knows what those changes are based on what properties and state each component receives, and can tell if it needs to update a component if any of its properties or state changed.
Take this tree as an example of a component hierarchy
Here we changed h to 8, so we also changed f because h is a child of f, and we also changed c because f is child of c and etcetera.
The key here is to think how React checks the component tree. It ill start at the root and see it changed. Then it'll check all the children and realize only c changed, so there is no need to check all the a and b branches. Then it'll check the c branch and realize only f changed so there is no need to check e and g. That operation is done on every component to calculate the minimum ammount of changes and also what needs to be updated.
If at any point you could mutate how a component is rendered it means React will need to check all of the branches and all of its children to know what changed because it can't rely on the state and the props to know when a branch changed and how. This would be painfully slow and make the whole React framework inviable.

I would say because of tracking the component state changes. If it isn't pure, it would cause side-effects every time it is executed. That way, would be very hard to know what has changed and furthermore how to react to these changes.
Pure functions, in other way, have the same output with the same input. Making it a lot easier to manage properties and track when something has changed, resulting a easier and predictable way to react to the change.

If they weren't pure functions in relation to their props then it would be violating the entire heirarchy/delegation structure that react provides and relies on.
Lets say you have two components, component A and Component B, and Component A is the parent to Component B. Component A has its own state based on some sort of data. When you pass a part of its state down as a prop to component B, you are establishing a contract between the two components that component B will delegate to component A to get the value of said prop.
This is in a sense a contract between the two components and the only way the contract isn't violated is that component B doesn't directly alter or change the passed down prop. That is what being a pure function means, that it doesn't mutate the prop directly. Of course you can clone the prop and then change it however you want that isn't a breaking of contract since at that point they aren't referencing the same values. But if you do mutate props directly you will also be mutating the parent component value. This can cause unintended side effects as well as cause issues with the react shadow dom differencing algorithm.
Here is that explained from the official react docs
https://facebook.github.io/react/blog/2015/02/24/streamlining-react-elements.html#problem-mutating-props-you-dont-own

You will discoverer "Why" understanding Reconciliation algorithm React uses for rendering.
Here you have all the information needed to understand what you want.
Part of that is well explained in Marco Scabbiolo's answer, but If you want to understand the way React works I strongly recommend you to read the post I've suggested.
Posting the answer here would be too much for a post and unnecesary because It has already explained by React Team. That's why I prefer giving you the source directly.

Related

How is Virtual DOM updated?

Imagine that you've built an application with ReactJs containing a hundred elements. Let's say that in some time, the state of component A changes, and for the sake of simplicity we assume it has only one element and no child component.
My question is: how is Virtual DOM updated in response to the state change?
After a few hours of research, I found two contradictory opinions:
The entire Virtual DOM is torn down; then it is rebuilt from scratch
Only the changed elements are updated in the Virtual DOM.
Unfortunately, official documentation is not clear about this. So, can anybody give the correct answer? (please with supporting reference)
[Edit] : Some parts are imcomplete here, think about reading the comment section !
React update a component when its state or a prop changes. It does a comparison between the previous JSX and the new one and re-render only the differences.
If the parent component has its state or a prop changed, it will be updated.
The child will not be refreshed unless a prop from the parent that is passed to it changes.
Note that the useEffect from the child is triggered first. Knowing that, If you do things that update the state in the child component, then it will be re-rendered everytime (Because the usEffect is triggered everytime if you don't set any dependencies).
Test from Stackblitz - Child Effect is triggered first
Article that made me notice it (I didn't know before this answer :D)
Here is how I understand things in React. To be short, the entire virtual DOM isn't rebuilt from scratch, it's not how JSX comparison works.
I don't have much sources about what I said, but here is the explanation about jsx update from the official documentation. Just that should be enough to eliminate the first point of your list.

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

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

React state vs. Redux state (real usecase)

I have read multiple tutorials how to make CRUD in React with Redux bot none of the authors explained why they are using Redux. (Like they are only using it for fancyness or because all other are using it.)
Citate from here:
People often choose Redux before they need it.
Through further researching i learned that Redux is good for:
Share state between components
Let some data be accessable in the entire application
It does not exist a wrong or right. But only the do what makes sense.
My usecase
I have a component that uses a shared component:
¦-- domains/FooManagement/Components/Editor.jsx <-- Most-parent of the editor
¦-- domains/FooManagement/Components/..the children of Editor.jsx
¦-- shared/Components/Tabs/Tabs.jsx <-- Most-parent of the tabs
¦-- shared/Components/Tabs/..the children of Tabs.jsx
Tabs.jsx is used in Editor.jsx.
Which is the right approach?
Approach 1: React state (I think its the right one)
Every dynamic rendering that can happen is stored in the state of Editor.jsx.
onClick on a tab (nested shared component) calls a callback written in Editor.jsx that updates the state in Editor.jsx. This state change then rerenders the new active tab
That means that on every other component like Editor.jsx that uses the same nested Tabs.jsx, the changes for the tabs must be handled in the editor.
Code example:
/**
* domains/FooManagement/Components/Editor.jsx
* or
* domains/BarManagement/Components/Editor.jsx
*/
onTabChange(activeTab) {
this.state.activeTab = activeTab;
this.setState(this.state);
}
I think this is the right approach because:
I dont need the state of the editor or the tabs component in the entire application. But only on this view one time. Like the short term duration definition.
Approach 2: Redux state
Editor.jsx has its own state
Tabs.jsx has its own state
States are stored in Redux
Editor.jsx dont passes data down to Tabs.jsx because Tabs.jsx takes the data from the Redux store
Benefit:
The code example above must not be in Editor.jsx because its not the editor's interests how the tabs component behaves. (Or should the editor interests?)
I think this is bad because
Its too much magic in here. Immagine there comes more components in the editor like sortables, tables, etc. In the Editor.jsx you will not see what can render your view. It is hidden in the other components.
But if its all handled in Editor.jsx, you have the overview and the control of all what must be rendered on any change.
What is the right approach for you?
speaking of real usecases, I'm working on an everyday growing project, at first, pure React state management seemed like a very convenient way to develop, and it was working just fine when the components structures were still somehow flattened, but as we go along it, the project gets more complicated and by complicated I mean, more component become nested, and one parent has a serie of nested children, so we have to pass props all the way from the parent to the most furthest child, and whenever we need to rerender the parent, all the children have to go through this cycle also, as for your case, if you know that your project won't get way more complicated, and Tabs.jsx won't have maybe something like form that contains further nested subForm that contains a Grid maybe, you surely don't need to complicate your life with Redux, but as I stated earlier, for us we started to notice that at this stage, integrating Redux would be considerable

React: best way to handle re-render of unrelated components

maybe this is very basic, but I'm still new to react:
I want to have different types of components - with (possibly) no relation to each other - that re-render on changing one specific value in my application. I tried the Provider store of mobx, but of course I received warnings, that you should not change the value of stores.
So for example
<RootElem>
<SimpleComp1>
.....
<ReRenderMeOnRootElemStateChange1 />
.....
</SimpleComp1>
<SimpleComp2>
.....
<ReRenderMeOnRootElemStateChange2 />
.....
</SimpleComp2>
</RootElem>
and the re-rendered components should have acces to the new value/state of the RootElem, so that they can change based on this new value.
What is the best way to do that? Where should I store my observable value for the re-render, and how can I make components listen to it, even if they are no children of the state changing component? I dont' want to pass the props all the way down to every single component, that should re-render on changing the observable value :)
Furthermore I'm wondering if you can make a component listen to another one's changes, even if they have no relationship to the each other in the component tree (except the application's root component).
Thanks!
React components re-render automatically by default when they receive new props. So if you simply pass values from <RootElem> down your component tree via props, everything should work as intended and the sub-components will re-render with the new value.
You can control whether or not a specific component should re-render by using its shouldComponentUpdate hook. I'd say that most of the time you won't need this unless you're trying to make a specific performance optimization.
You can also pass new values to the sub-components using context, though this approach is generally discouraged unless you have some very specific use cases for it and know what you're doing.

Reactjs - How to make components aware of the current view state?

Tools I'm Using: Reactjs 0.14.7, react-router 2.0.0 (Flux Pattern)
Note: I tagged Redux, just cause I got a hunch(I haven't used it) that what I'm experiencing might be one of the reasons people rave about it.
I understand that react-router already manages which parts of the
component tree are currently in view and renders the components based on the state of the current view tree.
Question:
But what if, based on the components in view, one component needs to know what other components are also in view and behave differently depending on what other components are in view(the view state)? What strategy would you suggest to allow components to be aware of the other components in view?
My Current Solution:
I currently am trying to use the URL to infer this global state, and even parsing it and putting it into a store in order for components to be aware of the view state by listening to changes from that store.
My Issue With This Solution:
In a nutshell managing that view state with a store becomes a highly entangled process with extra actions sprinkled all over the code.
1) Actions must be called for any user event that change the route.
2) Action need to be fired when navigating outside of components(I think its much cleaner to keep action firing in components(feel free to debate that one).
3) You must also consider the back button(currently using react-router onEnterHooks to catch when that happens).
Yet I really like the concept of encapsulating the view state because I can imagine that it creates a nice mental model and also smarter components, but just parsing the current URL and using a utility file to determine the current view state when needed, seems like a much easier/cleaner solution to manage then a store that contains the current view state.
Components should never need to know what other components are being rendered, that's one of the fundamental concepts of React. You're trying to extract the "view state" from your component tree, when your component tree should be determined by your state. If you're already using Flux, you need to keep that information in the store, where it will be made accessible to any component that subscribes.
Flux isn't about making development easier or faster for an individual, it's about enabling practices that make it easier to keep a mental model of what an application is doing. This might come at the expense of some simplicity.
Redux is a refinement of Flux that combines the multiple stores that can be subscribed to individually with a single large state tree, with different parts of the tree created by different "reducers" -- functions that take a state and an action and return a new state. It is exactly "a store that contains the current view state." What you describe is also a pretty good description of the type of development common in hacked together jQuery applications, the type of development React seeks to avoid.
I think the core of your misunderstanding falls into how React component's should be layered. It's a tricky topic, and re-aligning your thought process to accurately understand what is a state vs. prop in your model, is a unique challenge.
But the solution to this problem you are facing is simply to order your components more 'correctly'.
At a high level, each component should only care about the props that are passed to it, and not about anything else whatsoever. However, which props are passed are determined by it's parent Component. As a result, that parent can make those decisions, which then have an end result in the child.
As a simple but practical example;
var Parent = React.createClass({
funcA: function(){
this.setState({propB: 'something new!'});
},
render: function(){
return (
<div>
<ChildA propA={this.state.propA} funcA={this.funcA} />
<ChildB propB={this.state.propB} />
</div>
);
}
});
With this layout of concerns, ChildA is capable of handling user input, passing it to funcA which then impacts ChildB. But all of this happens without the Child components knowing anything about one another whatsoever.

Resources