上一章我们详述了Webpack配置 的核心原理与实践技巧,为项目构建奠定了坚实基础。本章将转向React框架探讨,通过剖析其组件化、虚拟DOM等特性,揭示Webpack配置如何与React深度结合,以提升应用性能与开发效率,实现更高效、灵活的现代前端项目构建。
React基本语法
React 概述
React 是一个用于构建用户界面的 JavaScript 库。
如果从 MVC 的角度来看,React 仅仅是视图层(View),也就是只负责视图的渲染,而并非提供了 完整的 M 和 C 的功能。
React 起源于 Facebook ,并于 2013 年 5 月开源
React 三个特点
- 1 声明式
- JSX 语法是声明式的,只需要描述页面长什么样子
- React.createElement() 是命令式
- 2 组件化
- 创建拥有各自状态的组件,再由这些组件构成更加复杂的 UI
- 组件逻辑使用 JavaScript 编写而非模版
- 3 一次学习,随处编写
- 不仅可以开发 web 应用(react-dom),还可以开发原生安卓或ios应用(react-native)
React基本使用
-
在html定义一个根标签
<div id="root"></div>
-
引入两个JS文件( 注意引入顺序 )
<!-- 提供react核心api--> <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <!-- 提供了react中操作dom的api--> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
-
创建react元素(类似html元素)
// 返回值:React元素 // 第一个参数:要创建的React元素名称 字符串 // 第二个参数:该React元素的属性 null或者对象 {id: 'box'} // 第三个及其以后的参数:该React元素的子节点 文本或者其他react元素 const title = React.createElement('h1', null, 'Hello React',...)
-
渲染 react 元素
ReactDOM.render(title, document.getElementById('root'))
特殊属性
-
添加样式要使用 className
const title = React.createElement('h1', { className: 'active' }, 'Hello React')
-
label的for属性,要改成htmlFor
const title = React.createElement('label', { htmlFor: 'abc' }, 'Hello React')
JSX
React.createElement()写起来太复杂了,所以推荐使用更加简洁的jsx
JSX是JavaScript XML,是React提供的Syntax Sugar(语法糖), 能让我们可以在JS中写html标记语言
const h1 = <h1 className="active">哈哈哈</h1>
注意: 浏览器并不认识jsx 所以需要引入babel将jsx编译成React.createElement的形式
编译 JSX 语法的包为:@babel/preset-react
<!-- babel的 CDN -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<!-- 并且script要进行设置 -->
<script type="text/babel">
const h1 = <h1 className="active"></h1>
ReactDOM.render(h1, document.getElementById('root'))
</script>
JSX中使用 JS 表达式
-
JSX中使用JS表达式的语法:
{}
-
注意:{} 里面可以写表达式,但是不能写语句(比如 if , for 等),
-
注意: {} 如果要写对象,应该是一个react元素或者是行内样式对象
const dv = <div className="abc">JSX中使用表达式: { 1 + 2 }</div> const dv = <div title={'我是标题'}>JSX中使用表达式: { 1 + 2 }</div> const dv = <div>JSX中使用表达式: { <span>JSX自身也是合法的JS表达式</span> }</div>
条件渲染
-
1 if / else
let box if (isloading) { box = <div>loading...</div> } else { box = <h1>数据加载完成~</h1> } ReactDOM.render(box, document.getElementById('root'))
-
2 三元
let box = isLoading ? <div>loading...</div> : <h1>数据加载完成~</h1> ReactDOM.render(box, document.getElementById('root'))
-
3 &&
let box = isLoading && <div>loading...</div> ReactDOM.render(box, document.getElementById('root'))
列表渲染
-
react中可以将数组中的元素直接渲染到页面上
-
因为jsx的原因,可以直接往数组中存储react对象
-
所以推荐使用数组的 map 方法
-
注意:应该给列表项添加 key 属性
let songs = [{id: 1,name: '东风破'},{id: 2,name: '菊花残'}] let list = <ul>{songs.map(item => <li key={item.id}>歌名:{item.name}</li>)}</ul> ReactDOM.render(list, document.getElementById('root'))
样式处理
-
1 行内样式
-
如果样式是数值,可以省略单位
<div style={ { color: 'red', fontSize: 30 } }>web</div>
-
-
2 类名(推荐!!!)
<div className="abc">web</div>
注意:
- React元素的属性名使用小驼峰命名法
- 没有子节点的React元素可以写成自闭和标签形式
事件处理
绑定事件
React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:
-
React 事件的命名采用小驼峰式(camelCase),而不是纯小写.比如:onMouseEnter、onFocus
-
使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串
const div = <div onClick={事件处理函数}></div>
事件对象
React 中的事件对象叫做:合成事件 (兼容所有浏览器,无需担心跨浏览器兼容性问题)
注意:
-
react中事件处理函数不能使用return false 阻止默认行为.需要使用事件对象的preventDefault()实现
-
如果在控制台打印事件对象,属性值都是null.一定要查看的话,调用事件对象.persist()方法
function handleClick(e) { e.preventDefault() //有效 console.log('事件对象', e) // return false 无效 } const div = ( <a href='https://www.baidu.com' onClick={handleClick}> 测试 </a> )
案例
-
需求:实现评论列表功能
-
如果有评论数据,就展示列表结构 li( 列表渲染 )要包含a标签
- name 表示评论人,渲染 h3
- content 表示评论内容,渲染 p
-
如果没有评论数据,就展示一个 h1 标签,内容为: 暂无评论!
-
根据自己的喜好添加样式
-
给a标签注册点击事件, 打印内容
const list = [ { id: 1, name: 'jack', content: 'rose, you jump i jump' }, { id: 2, name: 'rose', content: 'jack, you see you, one day day' }, { id: 3, name: 'tom', content: 'jack,。。。。。' } ]
// a标签的点击事件处理函数 function handle(e) { // return false //无效,因为这个handle不是真正的事件处理函数 e.preventDefault() // console.log(e.target) // 获取到点击的事件目标是真实的dom对象 if (e.target.nodeName === 'A') return console.log(e.target.textContent) } // 注意:jsx结构,有且仅有一个根标签 let div = ( <div> {list.length ? ( <ul> {list.map((item) => { return ( <li key={item.id} style={{ backgroundColor: 'skyblue' }}> <a href="" onClick={handle}> <h3 className="test">{item.name}</h3> <p className="test">{item.content}</p> </a> </li> ) })} </ul> ) : ( <h1>暂无评论</h1> )} </div> ) ReactDOM.render(div, document.getElementById('root'))