DEV Community

Cover image for Two way data binding in vue,react and vanilla js
Sourav das
Sourav das

Posted on

Two way data binding in vue,react and vanilla js

The react way

  const [nameS,setName]=useState({
        names:[
            {name:'sourav',age:30},
            {name:'Toton',age:50},
            {name:'Rick grimes',age:10}
        ],
        btn:"Switch all names"
    })

  // the function which is called when the input value is changed
      const twoWay=(event)=>
      {

        setName({
        names:[
            {name:event.target.value,age:35},
            {name:'Toton',age:50},
            {name:'Rick grimes',age:10}
        ],
            btn:"Name switched!"
        })
      }

      // passing the function as a props to NewComp named component
        <NewComp chan={twoWay}/>

        // NewComp.js is the stateless component
            <input type='text' onChange={props.chan} /> {/* calling the funtion in onChange event*/}
Enter fullscreen mode Exit fullscreen mode

The vue js way

<template>
    <h2>Tasks</h2>
    <!-- <Check/> -->
    <h4>{{msg}}</h4>
    <input type="text" v-model="msg">
    <!-- <p v-html="html"></p> -->
    <!-- <button v-bind:disabled='disbtn'>Thanos</button>111 -->
</template>
<script>
import Check from './Check'
export default {
    name:'So',
    components:{
        Check
    },
    data()
    {
        return(
        {
            name:'Sourav',
            html:' <h1>  Your name</h1>',
            disbtn:false,
            msg:'This is data'
        }

        )
    }
}
</script>
Enter fullscreen mode Exit fullscreen mode

The vanilla js way

// the html 
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Two way data binding</title>
</head>
<body>
  <h1 id='pr'>Hello</h1>
  <input type="text" id="two">
  <script src="app.js" charset="utf-8"></script>
</body>
</html>

// the app.js
const inp=document.getElementById('two')
const h1=document.getElementById('pr')
eve();
function eve()
{
  inp.addEventListener('keyup',cm)
}
function cm(e)
{
  h1.innerText=e.target.value
}

Enter fullscreen mode Exit fullscreen mode

I like the vue way what about you :)

Top comments (4)

Collapse
 
indoor_keith profile image
Keith Charles

I'm kind of confused why all three examples are all written very differently. React is changing an entire object when you type in a text field, while the vue and vanillaJS examples are only changing a single text value.

In any case, it might be worth mentioning, React doesn't actually have a two-way binding functionality. React follows a unitary data flow model, that is, data only flows down from parent to child, not vice versa. One way we get around this is by passing a callback to the child and letting that child run the callback with whatever value from the child we wish to provide.

Your React example sort of showcased this, but rather than change the value of the parent state from the child, you just change the value of the parent state using data from the parent state. Below would be an example of how we can imitate two-way binding in React:

const ChildComponent = (props) => {
  return (
    <input type="text" onChange={props.onChange} />
  );
};

const ParentComponent = () => {
  const [myMsg, setMyMsg] = useState('World');

  const handleChange = (event) => {
    const newMessage = event.target.value;
    setMyMsg(newMessage);
  }

  return (
    Hello, {myMsg}!
    <ChildComponent onChange={handleChange} />
  );
};
Enter fullscreen mode Exit fullscreen mode
Collapse
 
indoor_keith profile image
Keith Charles

Here's a svelte way of setting up two-way binding:

// Child.svelte
<script>
  export let value;
</script>

<input type="text" {value} on:input={(event) => value = event.target.value} />
Enter fullscreen mode Exit fullscreen mode
// Parent.svelte
<script>
  import Child from "Child.svelte";

  let myMsg="World";
</script>

<Child bind:value={myMsg} />
Enter fullscreen mode Exit fullscreen mode

Kinda crazy how little code it takes to get it set up with svelte πŸ˜‰

Collapse
 
buriti97 profile image
buridev

svelte looks like vanilla js

Collapse
 
aarone4 profile image
Aaron Reese

The Vue way intrinsically links the form data to the model which is brilliant right up to moment it isn't :)
If your form only represents part of the entity, or more than one entity or needs to auto add rows, or the model is stored in state it becomes harder to separate and manage. The react way with circular binding where the button updated state and state updates the form is actually easier to manage. I still like the Vue way better though.