网站内容更新机制(Vue和React的其中最重要的区别是什么?)

优采云 发布时间: 2021-10-15 10:37

  网站内容更新机制(Vue和React的其中最重要的区别是什么?)

  Vue 和 React 之间最重要的区别之一是它们管理数据更新的方式不同。Vue 基本上是一套基于 getter/setter 的订阅机制,依赖集合/依赖更新,而 React 使用显式的 Trigger 函数调用来更新数据,比如 setState。相比之下,Vue 的实现更细粒度。通过依赖集合,Vue 可以知道哪些数据更新需要重新计算。通过这种机制,Vue 可以优雅地实现计算属性,观察,包括 View 渲染。由于缺少这种细粒度的机制,React 往往需要一些其他的解决方案来提高性能,因此产生了诸如 PureComponent、ImmutableJS、shouldComponentUpdate 等钩子。

  Vue 和 React 如何更新视图?

  不同的是Vue知道组件数据中的value字段已经更新了,而React只知道组件的State发生了变化,并不知道哪些数据发生了变化。

  Vue 的视图重新渲染

  Vue 的订阅机制决定了它不仅知道更新了哪些数据,还知道更新数据后是否需要重新渲染当前组件和子组件的视图。这是通过“依赖采集”实现的。Vue 的视图模板会被编译成一个render 函数,并且在数据(data/props/computed)中定义了一个getter。每次调用各个组件的render函数,通过getter就可以知道哪些数据依赖哪些组件的views,下次给这些数据赋值,也就是调用setter,对应的view可以触发重新渲染,无关组件不需要再次调用render函数,节省开销。借用Vue作者做的图:(他称之为推送更新)

  

  例如:子组件Child使用propsvalue进行渲染,父组件Parent将datavalue作为props传递给子组件Child,一秒后更新数据。

  // Child.vue

export default {

name: "Child",

props: ["value"],

render(h) {

console.log("Child render");

return h("div", this.value);

}

};

// Parent.vue

import Child from "./components/Child";

export default {

data() {

return {

value: 1

};

},

components: { Child },

created() {

setTimeout(() => this.value = 2, 1000);

},

render(h) {

console.log("Parent render");

return h("div", [

h(Child, {

props: { value: this.value }

})

]);

}

};

复制代码

  控制台打印:

  Parent render

Parent render

//after 1000ms

Child render

Child render

复制代码

  由于 Parent 组件和 Child 组件的视图都使用了 Parent 的 datavalue,因此更改 value 的值会导致父子组件重新渲染。

  情况二:值不作为props传递给子组件Child,只用于组件自身的视图:

  

// Child.vue

export default {

name: "Child",

props: ["value"],

render(h) {

console.log("Child render");

return h("div", this.value);

}

};

// Parent.vue

import Child from "./components/Child";

export default {

data() {

return {

value: 1

};

},

components: { Child },

created() {

setTimeout(() => this.value = 2, 1000);

},

render(h) {

console.log("Parent render");

return h("div", [

h(Child),

this.value + ""

]);

}

};

复制代码

  控制台打印:

  Parent render

Child render

//after 1000ms

Parent render

复制代码

  改变值后,父组件重新渲染,但是子组件没有重新渲染,因为子组件的render函数没有采集父组件数据值的依赖。

  反应重新渲染

  当 setState 被调用时,React 并不关心哪些数据发生了变化,然后触发了组件的 shouldComponentUpdate。如果返回true,则调用render,然后以相同的方式更新所有子组件。如果返回 false,则阻止渲染方法调用和子组件。更新。也就是说更新视图的控制是由shouldComponentUpdate控制的,这个方法默认返回true。(Vue 作者称之为拉取更新):

  

  看一个例子:

  function Child(props) {

console.log("Child render");

return ;

}

class App extends React.Component {

constructor(props) {

super(props);

this.state = {

value: 1

};

}

componentDidMount() {

setTimeout(() => {

this.setState({

value: 2

});

}, 1000);

}

render() {

console.log("Parent render");

return (

);

}

}

const rootElement = document.getElementById("root");

ReactDOM.render(, rootElement);

复制代码

  控制台打印:

  Parent render

Child render

Parent render

Child render

复制代码

  即使视图不使用任何数据,调用 setState 的组件及其子组件也会重新渲染。当组件或节点较多时,更新数据可能会造成大量不必要的虚拟DOM构建,庞大的节点树也拖慢了diff的速度。这时候需要引入一些优化方案,比如 PureComponent 和 ImutableJS,PureComponent 使用 props 和 state 的浅比较来决定是否重新渲染。如果浅比较的结果相等,则组件及其子组件将不参与重新渲染。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线