当我使用react时,我发现这两个生命周期太相似了,componentWillReceiveProps接收nextProps作为参数,shouldComponentUpdate接收nextProps和nextState作为参数,所以我认为shouldComponentUpdate可以做同样的事情以及更多,为什么react保持componentWillReceiveProps方法,我想知道是什么这两种方法之间的区别
我知道React会创建一个虚拟DOM并比较差异,然后才更新实际DOM的实际元素,但是如果我手动更改它,效率会更高吗?通过getElementById还是通过使用jQuery函数?
<!DOCTYPE html>
<html>
<body>
<form>
Select your favorite browser:
<select id="myList" onchange="myFunction()">
<option></option>
<option>Google Chrome</option>
<option>Firefox</option>
<option>Internet Explorer</option>
<option>Safari</option>
<option>Opera</option>
</select>
<p>Your favorite browser is: <input type="text" id="demo" size="20"></p>
</form>
<script>
function myFunction() {
var mylist = document.getElementById("myList");
document.getElementById("demo").value = mylist.options[mylist.selectedIndex].text;
}
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud) 在下面查看此演示:
new Vue({
el: '#app',
data: {
flag: true
},
computed: {
style() {
let styleA = {
borderBottom: '1px solid red',
borderRight: '1px solid red'
};
let styleB = {
border: '1px solid green',
borderRight: '1px solid red'
}
return this.flag ? styleA : styleB
}
},
methods: {
changeStyle() {
this.flag = !this.flag;
}
}
})Run Code Online (Sandbox Code Playgroud)
.box {
width: 100px;
height: 100px;
}Run Code Online (Sandbox Code Playgroud)
<html>
<header>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
</header>
<body>
<div id="app">
<div class="box" :style="style"></div>
<button @click="changeStyle">changeStyle</button> …Run Code Online (Sandbox Code Playgroud)这是我为了调查 vue3 中列表的不必要的节点重新渲染而进行的一个小测试(vue2 具有相同的行为): https: //kasheftin.github.io/vue3-rerender/。这是源代码: https: //github.com/Kasheftin/vue3-rerender/tree/master。
我试图理解为什么 vue 在某些情况下会重新渲染 v-for 中已经渲染的节点。我知道(并将在下面提供)一些避免重新渲染的技术,但对我来说,理解该理论至关重要。
对于测试,我添加了一个虚拟 v-test 指令,该指令仅在触发 Mount/beforeUnmount 挂钩时记录。
测试1
<div v-for="i in n" :key="i">
<div>{{ i }}</div>
<div v-test="log2">{{ log(i) }}</div>
</div>
Run Code Online (Sandbox Code Playgroud)
结果:当n增加时,所有节点都重新渲染。为什么?如何避免这种情况?
测试2
Test2.vue:
<RerenderNumber v-for="i in n" :key="i" :i="i" />
RerenderNumber.vue:
<template>
<div v-test="log2">{{ log() }}</div>
</template>
Run Code Online (Sandbox Code Playgroud)
结果:工作正常。将内部内容从 test1 移动到单独的组件可以解决此问题。为什么?
测试3
<RerenderObject v-for="i in n" :key="i" :test="{ i: { i: { i } } }" />
Run Code Online (Sandbox Code Playgroud)
结果:不必要的重新渲染。似乎不允许在将对象发送到某个子组件之前在循环中动态构造对象,可能是因为{} != {}在 JavaScript 中。
测试4
<template>
<RerenderNumberStore …Run Code Online (Sandbox Code Playgroud) 我读到ReactJS与其他框架相比非常快,因为如果使用虚拟dom.
我无法理解的是,最终所有框架都必须在浏览器中推送dom对象.virtualDom如何帮助提高速度?
可以说如果我想添加10K节点列表,不应该为ReactJS和其他框架提供类似的DOM操作时间吗?
我知道这个主题显然已经讨论了很多,但我不确定如何研究我的问题,我的问题相当具体,我希望它遵循这里的规则。
我知道要决定是否更新 DOM,react 会将虚拟 DOM 与重新渲染的 DOM 进行比较。但我只是不明白它是否决定更新它 - 它是否更新特定重新渲染组件的所有元素,或者它是否知道只更新组件中已更改的元素?
提前致谢,
我刚刚开始学习 React JS。了解了反应如何更新渲染上的变化,虚拟 dom 如何帮助做到这一点。我是一名开发人员,以前在项目中使用过ajax。我了解了使用 React 的好处和效率。但是在学习过程中,我了解到 React virtual dom 用于仅更新发生更改的对象。如果我没记错的话,Ajax 也能实现同样的效果。有人澄清这两个概念。
这是我对DOM和浏览器如何工作的幼稚理解
每当DOM中的某些内容(真实dom)更改时,浏览器就会对该DOM重新绘制或重排。因此,用更简单的术语来说,每次DOM更改时,浏览器都需要重新计算CSS,进行布局并重新绘制网页。这是在真正的dom中花费时间的原因。
因此,React带有此虚拟DOM,它的实际作用是将更改批量进行批处理,然后调用一次将其应用于实际域。因此,最大程度地减少了回流和重涂。
那斯维尔特呢。如果直接操作DOM,它将如何控制浏览器的重绘/重排。
和 都h暴露createVNode于vue。
该文档似乎表明它们是相同的:
h() 函数是创建 VNode 的实用程序。也许更准确地命名为createVNode()。
但切换h到createVNode会抛出:
<script lang="ts">
import { createVNode, defineComponent, h } from 'vue'
export default defineComponent({
setup() {
// works
return () => h('strong', 'Foo')
// throws
return () => createVNode('strong', 'Foo')
},
})
</script>
Run Code Online (Sandbox Code Playgroud) 我在 React 中使用 CDN 的 Bootstrap 5。我有一个组件将在反应组件之一中使用 Popover。因此,根据文档,它说“您必须在 bootstrap.js 之前包含 popper.min.js 或使用包含 Popper 的 bootstrap.bundle.min.js / bootstrap.bundle.js 才能使弹出窗口正常工作!”
并且要初始化页面上的所有弹出窗口,请使用给定的 javascript 代码:
var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-
toggle="popover"]'))
var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
return new bootstrap.Popover(popoverTriggerEl)
})
Run Code Online (Sandbox Code Playgroud)
但我无法在我的反应组件中的 useEffect 中使用它,因为它返回“bootstrap.Popover(popoverTriggerEl)”对象,该对象在我的反应组件中未定义。
请问有人可以指导我吗?
刚开始反应,我想知道是否有任何解决方法可以克服此错误:
_registerComponent(...): Target container is not a DOM element.
编辑我想做的是:
我有一个反应功能,如:
ReactDOM.render(React.createElement(someFunction,{data:someData}),document.getElementById('someID')
这会产生一个dom喜欢:
<span>
<ul data-reactid='...'>blahhh</ul>
<div data-reactid='...'>
<div id='some-id1' data-reactid='...'>blahhh</div>
<div id='some-id2'data-reactid='...'>blahhhh</div>
</div>
</span>
Run Code Online (Sandbox Code Playgroud)
现在在上一个 react 调用的下一行,我有其他函数试图用上面创建的 div 做一些事情:
ReactDOM.render(React.createElement(someOtherReactFunction, { somePram: 'ImParam'}), document.getElementById('some-id1'));
Run Code Online (Sandbox Code Playgroud)
这给了我:
_registerComponent(...): Target container is not a DOM element.
但我可以看到它存在于 DOM 中
那么如何访问这个虚拟 domdiv呢?并在其中加载一些内容?
PS:我知道一种方法,dangerouslySetInnerHtml但正在寻找一种更好的方法
Pascal Precht 写了一篇关于 Angular 变化检测的精彩文章。虽然我知道 zone.js 和虚拟 DOM 是完全不同的概念,但 Angular 的 zone.js 相当于 React 的虚拟 DOM 吗?如果是,主要区别是什么,如果否,请简要说明原因。
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component{
constructor(props) {
super(props)
this.state = {
list: [{id: 1,val: 'aa'}, {id: 2, val: 'bb'}, {id: 3, val: 'cc'}]
}
}
click() {
this.state.list.reverse()
this.setState({})
}
render() {
return (
<ul>
<div onClick={this.click.bind(this)}>reverse</div>
{
this.state.list.map(function(item, index) {
return (
<Li key={item.id} val={item.val}></Li>
)
}.bind(this))
}
</ul>
)
}
}
class Li extends React.Component{
constructor(props) {
super(props)
}
componentDidMount() {
console.log('===did===')
}
componentWillUpdate(nextProps, nextState) {
console.log('===mount====')
}
render() {
return …Run Code Online (Sandbox Code Playgroud)virtual-dom ×13
reactjs ×10
javascript ×7
vue.js ×3
dom ×2
vuejs3 ×2
angular ×1
bootstrap-5 ×1
css ×1
dynamic-html ×1
html ×1
performance ×1
rendering ×1
svelte ×1
svelte-3 ×1
zone.js ×1