Is React's data-binding really one way? It seems like it is two way - angularjs

This is from a couple React tutorials that I'm currently reading:
the State drives what the guys at Facebook call one-way reactive data
flow, meaning that our UI will react to every change of state.
and
Typically UI’s have lots of state which makes managing state
difficult. By re-rendering the virtual DOM every time any state change
occurs, React makes it easier to think about what state your
application is in. The process looks something like this, Signal
to notify our app some data has changed→ Re-render virtual DOM ->
Diff previous virtual DOM with new virtual DOM -> Only update real DOM
with necessary changes.
The first quote seems to suggest that the data flow goes from React to the UI. But the second quote seems to suggest that it goes from the DOM to React which then re-renders the virtual DOM and the diff process than repaints the real DOM. This sounds a lot like Angular's two-way data binding.
Is this true? What am I missing? Is one-way reactive data flow just another name for Angular's two-way data binding?

I think it's necessary to make a distinction between React and Flux, both of which implement a uni-directional data flow. I'll only touch on React here.
In Angular a change to the DOM will directly mutate the value of bound scope variables in your controller thanks to angular's two-way data binding and the digest loop. It is two way because, of course, any change in your controller is also directly reflected in the view attached to it.
Think of Angular as Controller <--> View
In React a component always renders its DOM based on its props and internal state. A React component can listen to event being fired in the DOM it rendered, which might sound a bit like two-way data flow on the face of it but there is an important difference: An event fired on the DOM does not directly update the internal state of the component. The component must listen to the event and then explicitly update the component with the new state. This change of state then triggers the DOM to be re-rendered (if it needs to). In this way the components props and state are the single source of truth and always drive the DOM output. Of course changes in the DOM can affect the component but it is done in an indirect manner.
Think of React as Component State --> DOM --> New Component State --> New DOM

Angular's two way of binding's essence is that the view is bound both to the model and the user's input.
With React, the view is bound only to the state and a user's input cannot directly change the view, but triggers the component's own methods to update its state and Reacts job is to rerender the view so it reflects the state.

The flow here is:
Component
state-> virtual DOM -> DOM
This is always the flow, whether its initial render or second render.
The quoted bit is:state->virtual DOM -> DOM
newStateDifferentFromOldState -> virtual DOM
diff virtual DOM from 1 with virtual DOM from 2
Only update the elements of the DOM that are the net difference of performing 3.
e.g. 1->2->3->4, repeat in this order from 2 (2->3->4->2->3->4...so on)
This is in no way related to the concept of two way data binding.

Related

vdom is finally updating the dom (after diffing) any dom change should actually trigger repaint & reflow of entire tree, then what is the use of vdom?

This question was asked manier times whenever we change a dom , like
Method 1 :
document.getElementByID('root')="hello"; even for changing one dom element , the browser rerenders the whole dom and state of the other elements like input text boxes will be lost, and recomputes styling and layouts (.ie reflows and repaints )
It is fine till now.
Method 2:
What react does is it keeps a virtual dom which is a copy of real dom, whenever a state changes, it rerenders entire new vdom in memory and does diffing and identifies which nodes to be updated in real-dom and react updates only that part in real-dom ,thus saving time not re-rendering entire dom.
My Question is at the end of the day either we update the realdom using method 1 or by using a vdom , finally dom is getting updated which in turn should make the browser compute the whole layout and styles again, why people say it helps to update only some part of the UI?
** Please kindly refrain from answering the same diffing concept, vdom concept, updating the required parts concept,or repaint and reflow process i.e dom tree css tree and rendering engine etc...**
# My question is how vdom can stop browser repainting and reflowing when ultimately dom is getting updated which in turn makes reflow and repaint whole tree?
picture about what I am trying to ask:
Ignore my grammar, and correct me where ever I am wrong at concepts of dom, vdom, repaint and reflow.
VDom will generally not save you any repaints/reflows compared to well-written DOM manipulation.
The main benefit of it is that it that it allows for a declarative component API. You describe what the component is, and React figures out how to render it efficiently without re-generating extraneous DOM elements. The html changes will generally be smaller using this approach.
Performance benefits here are somewhat of a red-herring. Yes, Reacts vdom has optimizations such as batching renders, but these are optimizations for the vdom, not for the browser. Browser DOM operations are already very fast.

Best way to cause re-renders when non-state variables change

I have a separate data model object that I'm passing into UI components as a prop. I need portions of the UI to re-render when certain properties in the model object change. What's the best way of achieving this?
Do I create a dummy counter state and send the setState function into the data model to increment whenever I need the UI to change? This seems clunky and difficult to modularize for mapping certain changed properties to certain portions of the UI that need to be rerendered.

Hook re-render whole page on single change in a sub component

I create 2 Text Boxes one with hook and the another one with the old style, now in Hook mode when the user input change the textbox value the whole page rendered, but with old style there only the text-box rendered not the whole page, if you have the complex page with many objects like (Data Table, form, buttons, inputs, etc..) the single change on one of these components forced to re-render everything and it decease performance, for example typing in the text-box take time to effect on page and the delay time is more than user typing speed.
the one workaround solution is using the callbacks and useMem but if the page is complex(lots of objects as described, and all of these objects has many properties the callback and useMem is very very complicated to handle single object property.
SandBox Example
This is exactly how react hooks should work. what will cause a rerender in react? two things:
change in props
change in hooks or say in a better way hooks state
in the second case, the useInput state is changing so that causes a rerender and it's absolutely normal behavior. I think using custom hook in that way is not a good practice.
I recommend reading this article for more information on react rendering: https://www.codebeast.dev/usestate-vs-useref-re-render-or-not/

What effect do multiple state components have on react app?

According to the docs, one should avoid having multiple components with state. I am in the situation where I want to make a text box that automatically expands vertically as the user writes, and for that I'm using this trick http://www.impressivewebs.com/textarea-auto-resize/, which means I need to get the height of a component. Now, I've been playing around with it a bit, and it doesn't seem feasible to pass a ref to my parent component which contains state, so the easy way out would be to keep a piece of state in the component with the textbox, and then use the ref from there.
This got me thinking, how exactly do multiple state components negatively affect my app? Is it only maintainability / comprehensability? Or are there actual performance issues with it? I've noticed a lot of open source react components that you would just plug in to your app keep state, meaning if you use open source components, chances are you will have several state components in your app.
It's totally ok to use local state for this kind of tricks on DOM. It's even better approach, than to share such implementation details to parent components.
In general, use this places for state:
Application-wide data in stores outside React (redux, flux-store, observables)
Form temporary data can be placed in store also. But if don't need it anywhere else except form, it's better to place this data in form component.
Tricks on DOM, short living and very local state can be placed in component that just need it
are there actual performance issues with it?
No. If you'll place all your state in components, your application will become even faster. Because when you update local state, only this component and it's childs updates.
But you shouldn't do that, because it kills maintainability.
lot of open source react components that you would just plug in to your app keep state
If component doesn't allow you to control it through the props - it's bad component. Usually open source components written to be easier to use, so they provide nice defaults, that allow you to just place component to your application, and be happy with that.
For example, Tabs component usually controlls selected tab using local state. But also it takes selectedTab and callback onSelect, so you can control it by yourself.
Stupid components (like your textarea component) should not have state with data. But they can have their own UI state.
In this case you can easily keep textarea height in state of stupid component.

attaching event handlers to react components using jquery

I know this is the proper way to do -
Attach handlers on react components using attributes such as onClick, onBlur etc.
If attaching custom events then attach them in componentDidMount so that it always gets attached on every rendering.
https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#under-the-hood-autobinding-and-event-delegation
However, what happens when an event is attached to a DOM element using jquery ? Why am I not able to listen to those events ? I am attaching them out side componentDidMount. However the event handler should get trigerred the first time atleast ?
I was debugging some react code which was attaching an handler to it directly, but it was not trigerring the handler at all. Why was that ?
Without code example it's difficult to know for sure but more than likely you're trying to bind an event using jQuery to some react-generate DOM element. So depending where you do the bind, you're probably using a jQuery selector which returns no results because React hasn't rendered that element to the DOM at the time the selector is being run.
This is why, if you are going to use jQuery binding, you should make sure you do so as part of the component lifecycle that ensures the element is actually rendered to the DOM before you are trying to select it with jQuery. So that's why the recommendation is to put this kind of code inside componentDidMount and clean it up in componentWillUnmount.

Resources