Can anyone explain the difference between Reacts one-way data binding and Angular's two-way data binding
Asked Answered
N

5

154

I'm a bit fuzzy on these concepts, If I build the same ToDo app completely in AngularJS and ReactJS--- what makes the React ToDo use one-way data binding vs the AngularJS's two-way data binding?

I understand that React sort of works like

Render(data) ---> UI.

How is this different from Angular?

Nottinghamshire answered 29/12, 2015 at 22:11 Comment(0)
C
215

Angular

When angular sets up databinding two "watchers" exist (this is a simplification)

//js
$scope.name = 'test';
$timeout(function()  { $scope.name = 'another' }, 1000);
$timeout(function()  { console.log($scope.name); }, 5000);

<!-- html --->
<input ng-model="name" />

The input will start out with test, then update to another in 1000ms. Any changes to $scope.name, either from controller code or by changing the input, will be reflected in the console log 4000ms later. Changes to the <input /> are reflected in the $scope.name property automatically, since ng-model sets up watches the input and notifies $scope of the changes. Changes from the code and changes from the HTML are two-way binding. (Check out this fiddle)

React

React doesn't have a mechanism to allow the HTML to change the component. The HTML can only raise events that the component responds to. The typical example is by using onChange.

//js
render() { 
    return <input value={this.state.value} onChange={this.handleChange} />
}
handleChange(e) {
    this.setState({value: e.target.value});
}

The value of the <input /> is controlled entirely by the render function. The only way to update this value is from the component itself, which is done by attaching an onChange event to the <input /> which sets this.state.value to with the React component method setState. The <input /> does not have direct access to the components state, and so it cannot make changes. This is one-way binding. (Check out this codepen)

Cammiecammy answered 29/12, 2015 at 22:37 Comment(5)
Thanks, this was extremely informative. So I guess Angular works more like UI <----> Data in contrast to React's Render(data)--->UI ?Nottinghamshire
Yes, thats a very concise way to put itCammiecammy
To be clear, the distinguishing thing about data binding is that it does the updates for you automatically. In the React example, UI → data is still happening, it's just that it doesn't happen by default - you have to manually set up the onChange listener and run handleChange. But from there, because of React's one way data binding, the data → UI update does happen automatically.Oneway
FYI the fiddle needed a reference to AngularJS 1.1.1, I guess the ref to AngularJS 1.0.1 wasn't valid anymore, was getting a 404. Oddly using identical code in a brand new fiddle (with a 1.1.1 reference) fails, don't know what that's about.Faucet
So by the sound of it, two-way binding is smarter (since it syncs both way without manual). So why React changes to one-way binding then?Jat
H
235

I made a little drawing. I hope it's clear enough. Let me know if it's not !

2 ways data binding VS 1 way data binding

Harrie answered 1/6, 2016 at 10:56 Comment(11)
What's 'Titre de l'annonce'?Bidding
'Ad title' in frenchShere
@DamienRoche as far as I understand this concept the difference is next: In two way data binding: changing data changes view and vice versa — updating input inside view updates data. In on way data flow: updating data updates view but updating input in view will not update data unless programmer do it explicitly by attaching listener to input which will update data. Hope that will make it a bit more clear for you.Trivial
Thanks, @Patrick for your message. I am always very happy to feel something I did is useful for othersHarrie
link is broken @Harrie could you share the image in the post?Adonai
@Adonai I can see the image. I guess it's fixed now. The image is hosted by StackoverflowHarrie
@Harrie I think the first drawing is misleading, since the 2 watchers are separate, independent, doing their 1-way job. And your drawing suggests that a change in any direction goes through the two, whereas in reality it goes through one (depending on which way)Bacteriology
@Harrie isn't 1 way more work, since we have to manually write listeners and is not automatic as 2 way? Is there any advantage to 1 way over 2 way binding?Urinary
@Urinary It's what I thought before, but the 1 way is easier to debug, have better performance and your code is just clearer in my point of viewHarrie
The point raised by @Cake_Seller is crystal clear, thanks. Tutorials over the web do mention other paradigms, and also refer to them as React's one-way data flow, such as the parent-to-child data flow (via props) and even refer to Redux/Flux architecture's Unidirectional data flow. While all these are indeed a one-way data flow, it may be confusing to a beginner.Wyatt
This gave me a better understanding even quicker than reading big paragraphs.Landtag
C
215

Angular

When angular sets up databinding two "watchers" exist (this is a simplification)

//js
$scope.name = 'test';
$timeout(function()  { $scope.name = 'another' }, 1000);
$timeout(function()  { console.log($scope.name); }, 5000);

<!-- html --->
<input ng-model="name" />

The input will start out with test, then update to another in 1000ms. Any changes to $scope.name, either from controller code or by changing the input, will be reflected in the console log 4000ms later. Changes to the <input /> are reflected in the $scope.name property automatically, since ng-model sets up watches the input and notifies $scope of the changes. Changes from the code and changes from the HTML are two-way binding. (Check out this fiddle)

React

React doesn't have a mechanism to allow the HTML to change the component. The HTML can only raise events that the component responds to. The typical example is by using onChange.

//js
render() { 
    return <input value={this.state.value} onChange={this.handleChange} />
}
handleChange(e) {
    this.setState({value: e.target.value});
}

The value of the <input /> is controlled entirely by the render function. The only way to update this value is from the component itself, which is done by attaching an onChange event to the <input /> which sets this.state.value to with the React component method setState. The <input /> does not have direct access to the components state, and so it cannot make changes. This is one-way binding. (Check out this codepen)

Cammiecammy answered 29/12, 2015 at 22:37 Comment(5)
Thanks, this was extremely informative. So I guess Angular works more like UI <----> Data in contrast to React's Render(data)--->UI ?Nottinghamshire
Yes, thats a very concise way to put itCammiecammy
To be clear, the distinguishing thing about data binding is that it does the updates for you automatically. In the React example, UI → data is still happening, it's just that it doesn't happen by default - you have to manually set up the onChange listener and run handleChange. But from there, because of React's one way data binding, the data → UI update does happen automatically.Oneway
FYI the fiddle needed a reference to AngularJS 1.1.1, I guess the ref to AngularJS 1.0.1 wasn't valid anymore, was getting a 404. Oddly using identical code in a brand new fiddle (with a 1.1.1 reference) fails, don't know what that's about.Faucet
So by the sound of it, two-way binding is smarter (since it syncs both way without manual). So why React changes to one-way binding then?Jat
T
15

Two-way data binding provides the ability to take the value of a property and display it on the view while also having an input to automatically update the value in the model. You could, for example, show the property "task" on the view and bind the textbox value to that same property. So, if the user updates the value of the textbox the view will automatically update and the value of this parameter will also be updated in the controller. In contrast, one way binding only binds the value of the model to the view and does not have an additional watcher to determine if the value in the view has been changed by the user.

Regarding React.js, it was not really designed for two way data binding, however, you can still implement two-way binding manually by adding some additional logic, see for example this link. In Angular.JS two-way binding is a first class citizen, so there is no need to add this additional logic.

Two answered 29/12, 2015 at 22:20 Comment(0)
A
1

While React doesn't provide two-way data bindings out of the box, there are many use cases for which they seem like the natural state management mechanism to work with -- especially when working on complex single-page or React Native applications or with lots of asynchronously coordinated data, transformations, and logic.

react-bindings adds convenient two-way bindings support and tools for React / React Native and react-waitables builds on top of it with additional async support. These packages, especially used in combination with React hooks and contexts, mean not having to choose strictly between unidirectional and bidirectional models just because of working with React vs Angular.

Adversity answered 5/7, 2022 at 3:29 Comment(0)
S
0

One way data binding is very simple, except in React we rarely use the word binding to refer how the data flows.

  const fn = (a) => { return ... }

If a value is provided as a, we'll use that value in the function scope. The above is programming 101.

  <Title name={"Hello"} />

The above line doesn't mean anything would magically happen other than the fact that "Hello" is sent to Title function and set one prop to "Hello", if you insist to use the word bind here, that's where the bind happens.

Whether you want to use this prop to display or wire with another state or whatever, you have to code yourself! There's no other magic. Btw, this is called props in React. And props is more or less a function's input argument coded in an object format. So the more accurate definition of this "bind" in React should be called assignment. In React source code, you'll see something very quickly after the element is created.

  element.props = { name: "Hello" }

And believe it or not, there's no other code in React that does anything to do with this "bind" later on.

Example

Use the input example,

<input value={value} onChange={onChange} />

If we give a value to input, the input would pick up the value to display it. If you change the value, you are intending to change the display.

Why does the value change? It can't by default. You have to change it by either listening to a system event like onChange or some business logic like setTimeout or whatever way you can ever imagine. But the change is an action, you perform the action therefore you can handle the action by changing the value. I guess this is where the "One-way" comes from. Essentially nothing is free.

Confusion

What gets us confused is that DOM element has its own state or properties. For example, we can do el.textContent="abc" without using React.

<input />

If we just code like this, we still see the value on screen changes after we type in anything. But this behavior has nothing to do with React, it's the DOM element functionalities. React refers to the first version as controlled element. Essentially React overwrites the DOM way.

NOTE

To be honest, only after I stopped using the word "binding" for these cases, I started to understand what they are. But that could be just me.

Sin answered 29/9, 2021 at 18:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.