preface

Following on from the previous article, this article will talk about the similarities and differences between Vue and React regarding states.

state vs data

In Vue, internal variables are defined by declaring data. Data translated into Chinese is the meaning of data, which also conforms to the overall design of Vue. Responsive data, a change of data will cause a series of associated actions. In React, it becomes the keyword state, which translates to the meaning of state, and is used to drive view updates through the state.

In Vue, data is responsive, and this response has two aspects:

  • JS memory variable value changes, notifying DOM to draw
  • When the content of an element in the DOM changes, JS is notified that the value of a variable in memory has changed

In terms of implementation, Vue makes use of JS API to realize overloaded point operator, and uses explicit declarations such as V-Model to timely feed back the update of memory variables by listening to DOM elements. This approach of Vue actually has a certain performance loss, but it brings low threshold for developers, high efficiency.

React adopts explicit declaration (setState) in the state update section. After the state update, call the render function to inform DOM to draw, and the transfer of data stream is one-way (of course, it is also simple to implement reverse update in Vue, but it is not advocated officially).

Let’s look at a simple example of implementing a binding of the input values of the input component:

Vue:
<template>
    <input type="text" v-model="value" />
</template>
<script>
    export default {
        data() {
            return {
                value: ""
            }
        }
    }
</script>

React:
function render() {
    const [value, setValue] = useState("");
    return (
       <input type="text" onChange={(e) => setValue(e.target.value)} />
    )
}
Copy the code

Vue can use the v-model directive to correlate data in a responsive manner, reducing the need to write part of the listening callback code, but in fact, Vue can also be written like this:

Vue:
<template>
    <input type="text" :value="value" @input="setValue">
</template>
<script>
    export default {
        data() {
            return {
                value: ""
            }
        },
        methods: {
            setValue(e) {
                this.value = e.target.value;
            }
        }
    }
</script>
Copy the code

Although you wouldn’t write this in real development, Vue already provides ready-made instructions.

In Vue, there is a nice feature called computed that listens for changes in dependencies and computs all the time. For example, if we want the third input field to be the value of the first two input fields, we would write:

Vue:
<template>
    <input type="text" v-model="a" /> +
    <input type="text" v-model="b" /> =
    <input type="text" v-model="sum" />
</template>
<script>
    export default {
        data() {
            return {
                a: "",
                b: "",
            }
        },
        computed: {
            sum() {
                return this.a + this.b
            }
        }
    }
</script>
Copy the code

Computed dependency collection

Wrote here, I produced a curious point, how do you determine the sum function call time, intuitive response is to collect the function dependency, in the React, will require developers to an array of deps directly, as long as each comparison array can determine a reference to the address, and does not require developers to declare in Vue. There are two common ways to collect dependencies

  • Static lexical analysis
  • Gets after executing the function

Static analysis compares CPU consumption performance, for example:

computed: {
    sum() {
        const a = "x";
        const b = a;
        const c = b;
        return this[c] * 2
    }
}
Copy the code

Obviously, this function depends on the x variable, but to push to the x variable requires deriving c => b => a => “x” in turn, which would be more complicated if circular references were involved. Obviously Vue will not go down this route. Vue executes the sum function once, and then takes all the variables that are called get and makes up the dependencies. After reading the data, Vue proves that Vue does the same thing.

If the code looks like this:

Computed: {sum() {if (math.random () < 0.5) {return; } return this.a + this.b } }Copy the code

In this case, half the time, the data will not be updated, because the dependencies are identified at the time of first execution. If you want to implement this requirement in React, you can encapsulate your own custom hooks that simulate computed.

Logic reuse

Let’s talk about the reusability of logic. Before React had Hooks, it was similar to Vue. The UI description and logic were mixed together. So in peacetime development most of the scene is to copy the form of code to do, can do some things are relatively limited, such as draw tool library, elaborate design a component specification. This changed a bit after React Hooks came into existence, where UI descriptions and logic were naturally separated, and logic reuse became a logical thing to do.

conclusion

  • In terms of data driven UI, React is not fundamentally different from Vue. The UI layer is notified of state changes, but Vue is implicit. React is explicitly called with setState

  • Vue makes a lot of “gadgets” for developers to help them be more productive

  • In terms of the development experience, there are a lot of factors that affect people’s coding habits