前言
我是歌谣 我有个兄弟 巅峰的时候排名c站总榜19 叫前端小歌谣 曾经我花了三年的时间创作了他 现在我要用五年的时间超越他 今天又是接近兄弟的一天人生难免坎坷 大不了从头再来 歌谣的意志是永恒的 放弃很容易 但是坚持一定很酷 微信公众号前端小歌谣 关注公众号带你进入前端学习交流群
代码案例
/* * 在React我们操作的元素被称为React元素,并不是真正的原生DOM元素, * React通过虚拟DOM 将React元素 和 原生DOM,进行映射,虽然操作的React元素,但是这些操作最终都会在真实DOM中体现出来 * 虚拟DOM的好处: * 1.降低API复杂度 * 2.解决兼容问题 * 3.提升性能(减少DOM的不必要操作) * * 每当我们调用root.render()时,页面就会发生重新渲染 * React会通过diffing算法,将新的元素和旧的元素进行比较 * 通过比较找到发生变化的元素,并且只对变化的元素进行修改,没有发生的变化不予处理 * */
代码案例
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>虚拟DOM</title> <script src="script/react.development.js"></script> <script src="script/react-dom.development.js"></script> <script src="script/babel.min.js"></script> </head> <body> <button id="btn">点我一下</button> <hr> <div id="root"></div> <script type="text/babel"> //创建一个数据 const data = ['孙悟空', '猪八戒', '沙和尚']; // 创建列表 const list = <ul> {/*data.map(item => <li key={item}>{item}</li>)*/} {data.map((item, index) => <li key={index}>{item}</li>)} </ul>; // 获取根元素 const root = ReactDOM.createRoot(document.getElementById('root')); // 渲染元素 root.render(list); /* * 在React我们操作的元素被称为React元素,并不是真正的原生DOM元素, * React通过虚拟DOM 将React元素 和 原生DOM,进行映射,虽然操作的React元素,但是这些操作最终都会在真实DOM中体现出来 * 虚拟DOM的好处: * 1.降低API复杂度 * 2.解决兼容问题 * 3.提升性能(减少DOM的不必要操作) * * 每当我们调用root.render()时,页面就会发生重新渲染 * React会通过diffing算法,将新的元素和旧的元素进行比较 * 通过比较找到发生变化的元素,并且只对变化的元素进行修改,没有发生的变化不予处理 * */ document.getElementById('btn').onclick = function (){ // 重新渲染页面 //创建一个数据 const data = ['唐僧', '孙悟空', '猪八戒', '沙和尚']; // 创建列表 const list = <ul> {/*data.map(item => <li key={item}>{item}</li>)*/} {data.map((item, index) => <li key={index}>{item}</li>)} </ul>; // 渲染元素 root.render(list); /* * 旧数据 * ul * li>孙悟空 * li>猪八戒 * li>沙和尚 * 新数据 * ul * li>孙悟空 * li>猪八戒 * li>沙和尚 * 比较两次数据时,React会先比较父元素,父元素如果不同,直接所有元素全部替换 * 父元素一致,在去逐个比较子元素,直到找到所有发生变化的元素为止 * 上例中,新旧两组数据完全一致,所以没有任何DOM对象被修改 * * * 旧数据 * ul * li>孙悟空 * li>猪八戒 * li>沙和尚 * 新数据 * ul * li>tom * li>猪八戒 * li>沙和尚 * * 上例中,只有第一个li发生变化,所以只有第一个li被修改,其他元素不变 * * 当我们在JSX中显示数组中,数组中每一个元素都需要设置一个唯一key,否则控制台会显示红色警告 * 重新渲染页面时,React会按照顺序依次比较对应的元素,当渲染一个列表时如果不指定key,同样也会按照顺序进行比较, * 如果列表的顺序永远不会发生变化,这么做当然没有问题,但是如果列表的顺序会发生变化,这可能会导致性能问题出现 * * * 旧数据 * ul * li>孙悟空 * li>猪八戒 * li>沙和尚 * 新数据 * ul * li>孙悟空 * li>猪八戒 * li>沙和尚 * li>唐僧 * * 上例中,在列表的最后添加了一个新元素,并没有改变其他的元素的顺序,所以这种操作不会带来性能问题 * * * * 旧数据 * ul * li>孙悟空 * li>猪八戒 * li>沙和尚 * 新数据 * ul * li>唐僧 * li>孙悟空 * li>猪八戒 * li>沙和尚 * * 上例中,在列表的最前边插入了一个新元素,其他元素内容并没有发生变化, * 但是由于新元素插入到了开始位置,其余元素的位置全都发生变化,而React默认是根据位置比较元素 * 所以 此时,所有元素都会被修改 * * 为了解决这个问题,React为列表设计了一个key属性, * key的作用相当于ID,只是无法在页面中查看,当设置key以后,再比较元素时, * 就会比较相同key的元素,而不是按照顺序进行比较 * 在渲染一个列表时,通常会给列表项设置一个唯一的key来避免上述问题 * (这个key在当前列表中唯一即可) * 注意: * 1.开发中一般会采用数据的id作为key * 2.尽量不要使用元素的index作为key * 索引会跟着元素顺序的改变而改变,所以使用索引做key跟没有key是一样的 * 唯一的不同就是,控制台的警告没了 * 当元素的顺序不会发生变化时,用索引做key也没有什么问题 * 旧数据 * ul * li(key=孙悟空)>孙悟空 * li(key=猪八戒)>猪八戒 * li(key=沙和尚)>沙和尚 * 新数据 * ul * li(key=唐僧)>唐僧 * li(key=孙悟空)>孙悟空 * li(key=猪八戒)>猪八戒 * li(key=沙和尚)>沙和尚 * */ }; </script> </body> </html>