文章目录
一、虚拟 DOM 的创建方式
- 原生 JS 创建
React 提供内置方法React.createElement(type, props, ...children),是JSX 的底层编译结果,所有 JSX 最终都会被 Babel 编译为该方法调用。
语法参数
javascript
//1.创建虚拟DOM,创建嵌套格式的dom
const VDOM=React.createElement('h1',{id:'title'},React.createElement('span',{},'hello,React'))
//2.渲染虚拟DOM到页面
ReactDOM.render(VDOM,document.querySelector('.test'))
- JSX 创建(推荐)
JSX 是JavaScript 的语法扩展,并非标准 JS,需通过 Babel 编译,最终转为React.createElement调用。
javascript
//1.创建虚拟DOM
const VDOM = ( /* 此处一定不要写引号,因为不是字符串 */
<h1 id="title">
<span>Hello,React</span>
</h1>
)
//2.渲染虚拟DOM到页面
ReactDOM.render(VDOM,document.querySelector('.test'))
核心特点: 写法接近 HTML,开发效率远高于原生 JS 创建 本质是语法糖,不依赖浏览器,运行前已编译为纯 JS
二、JSX 语法规则
JSX 融合 HTML 和 JS 特性,有专属语法规范,必须遵循否则编译报错,核心规则如下:
-
定义虚拟DOM,JSX不是字符串,不要加引号
-
标签中混入JS表达式的时候使用{}
-
样式的类名指定不能使用class,使用
className -
内敛样式要使用
{``{}}包裹 -
不能有多个根标签,只能有一个根标签
-
JSX的标签必须正确结束(自结束标签必须写/)
-
JSX中html标签应该小写,React组件应该大写开头。如果小写字母开头,就将标签转化为 html 同名元素,如果 html 中无该标签对应的元素,就报错;如果是大写字母开头,react 就去渲染对应的组件,如果没有就报错
-
如果表达式是空值、布尔值、undefined,将不会显示
三、函数式组件
函数式组件是纯 JavaScript 函数,接收props参数,返回JSX / 虚拟 DOM,无自身状态,无this指向。
两种写法
箭头函数(推荐,简洁无 this 问题)
普通函数(传统写法,可省略 return 括号)
注意: 组件名称必须以大写字母开头。
四、类式组件
将函数组件转换成 class 组件
通过以下五步将 Clock 的函数组件转成 class 组件:
- 创建一个同名的 ES6 class,并且继承于 React.Component。
- 添加一个空的 render() 方法。
- 将函数体移动到 render() 方法之中。
- 在 render() 方法中使用 this.props 替换 props。
- 删除剩余的空函数声明。
特点
有自身状态state,支持复杂状态管理
有完整的生命周期钩子
存在this指向问题,事件绑定需手动处理
五、事件绑定
React 事件为合成事件,分函数式、类式组件两种场景 ,核心规则:事件名小驼峰命名,传入函数引用。
- 函数式组件的事件绑定
javascript
const App = () => {
const handleClick = (msg) => console.log('点击了:', msg)
return <button onClick={() => handleClick('React')}>点击传参</button>
}
- 类式组件的事件绑定
类方法严格模式下this默认undefined,需手动绑定到组件实例
六、this 指向问题(重点:类式组件)
- ES6 类的方法默认运行在严格模式下,方法本身的this为undefined,而非全局window,函数式组件无this,因此不存在 this 指向问题
- 解决方式(对应类式组件事件绑定 4 种方式)
构造器中 bind 绑定:适合复杂组件 类的实例方法
箭头函数:无需手动绑定
render 中 bind 绑定:适合简单组件
render 中箭头函数包裹:适合临时传参场景
七、state 属性
-
核心概念
组件私有可修改的动态数据(如表单值、计数),修改后组件自动重新渲染,遵循不可直接修改原则,需通过指定方法更新。
-
类式组件使用
初始化:直接定义类实例属性
state = { 键值对 },通过this.state.属性读取修改:必须用this.setState(新状态/回调函数),异步操作,依赖旧状态用回调函数,支持对象自动合并。
-
函数式组件使用
无this,直接通过变量和方法操作,对象 / 数组修改需手动解构旧值
八、props 属性
- 核心概念
组件的外部传入属性 ,实现父向子单向通信 ,props 为只读对象,禁止修改,支持传递任意类型数据(含函数、组件)。 - 基础使用
父组件:组件标签上写属性,非字符串类型用 {} 包裹
子组件:函数式通过参数接收,类式通过this.props接收,均可解构获取属性。
javascript
// 子组件(函数式)
const Child = ({ name, age }) => <div>{name}-{age}</div>
// 父组件
const Parent = () => <Child name="React" age={10} />
- 特殊属性与增强
props.children:内置属性,接收组件标签之间的子内容