React特性与优势
- 声明式编程:通过JSX描述UI状态,自动处理DOM更新
- 组件化架构:将UI拆分为独立可复用的代码单元(函数组件/类组件)
- 高性能机制:
- 虚拟DOM减少直接操作真实DOM的成本
- Diffing算法最小化重绘范围
- 跨平台支持:React Native开发原生应用
React 使用
React 是一个第三方的框架库,所以在使用前要先把相关的库文件引入。
jsx
// 引入react核心库
<script type="text/javascript" src="../js/react.development.js"></script>
// 引入react-dom,用于支持react操作DOM
<script type="text/javascript" src="../js/react-dom.development.js"></script>
// 引入babel,用于将jsx转为js
// Babel 还可以将 ES6 代码转为 ES5 代码,这样我们就能在目前不支持 ES6 浏览器上执行 React 代码。Babel 内嵌了对 JSX 的支持
<script type="text/javascript" src="../js/babel.min.js"></script>
React 是基于 jsx 语法去实现,所以需要明确 script 的类型为 text/babel
jsx
<script type="text/babel">
// 这里可以写jsx语法
</script>
基本使用
jsx
// 此处一定要写babel
<script type="text/babel" >
{/* 1.创建虚拟DOM */}
{/* 此处一定不要写引号,因为不是字符串 */}
const VDOM = <h1>Hello,React</h1>
{/* 2.渲染虚拟DOM到页面 */}
ReactDOM.render(VDOM,document.getElementById('test'))
</script>

虚拟DOM的两种创建方式
- 1.纯JS方式(一般不用)
- 2.JSX方式
jsx
// 1.纯JS方式
const VDOM = React.createElement('h1',null,'Hello,React')
// 2.JSX方式
const VDOM = <h1>Hello,React</h1>
//2.渲染虚拟DOM到页面
ReactDOM.render(VDOM,document.getElementById('test'))
// 关于虚拟DOM:
// 1.本质是Object类型的对象(一般对象)
// 2.虚拟DOM比较"轻",真实DOM比较"重",因为虚拟DOM是React内部在用,无需真实DOM上那么多的属性。
// 3.虚拟DOM最终会被React转化为真实DOM,呈现在页面上。
JSX 语法
一种特殊的 js 语法糖,可以在代码中把 html 标签当对象使用,其可以总结成以下几个特点:
- 不加任何引号
以前在 js 中使用 html 标签都是加上引号当成字符串使用,而在 jsx 语法中不用加引号,直接当对象使用。
jsx
// 以前
var html = '<h1>Hello,React</h1>';
// 现在
var html = <h1>Hello,React</h1>;
- 标签一定要有对应的结束标标签或结束标识:
有时候我们在写 html 结构的时候,都没有把对应的结束标识加上,但浏览器能正常解析,但在 jsx 语法当中,则要强制写标准的 html 结构 这一段 html 标签在浏览器是能正常解析
jsx
<input type="text" value="React">
{/* 这一段在 jsx 语法当中则会报错 */}
var html = <input type="text" value="React">;
{/* jsx 正确写法应该是这样的 */}
var html = <input type="text" value="React" />;
var div = <div>React</div>;
- 只能有一个根节点
在 jsx 语法当中,最顶层的结构一定只有一个节点,不能出现兄弟节点。
jsx
var html =
<div>
<h1>Tom</h1>
<h1>Lucy</h2>
</div>
- 不能在标签当中加注释
在 jsx 语法当中,html 标签是一个对象,是一种数据结构,而不是真实的 DOM 节点,也不是字符串,所以在标签当中不能添加注释。 下面的代码是在标签当中添加了注释,所以会报错。
jsx
var html =
<div>
<!--不能添加注释,这里会报错-->
<h1>Tom</h1>
<h1>Lucy</h2>
</div>
- jsx 语法允许 html 标签和 javascript 代码混写
在 jsx 语法当中,要在 html 标签中用到 js 代码,则用花括号({expression})括起来,注意只有一个大括号{react}。相对于 Vue,Vue 是用两个大括号{{vue}}来渲染数据的,React 是单向数据绑定的,Vue 是双向数据绑定的。
jsx
var name = "React";
var style = {fontSize: '12px', color: 'red'};
var html = <span style={style}>{name}</span>;
{/* 最终上面的代码将会解析成 */}
<span style="font-size:12px; color:red">DK</span>
- 样式的类名指定不要用class,要用className。
jsx
<h2 className="title" id={myId.toLowerCase()}>
<span style={{color:'white',fontSize:'29px'}}>{myData.toLowerCase()}</span>
</h2>
JSX高频场景
- JS表达式
在JSX中可以通过
大括号语法{}
识别JavaScript中的表达式,比如常见的变量、函数调用、方法调用等等
- 使用引号传递字符串
- 使用JS变量
- 函数调用和方法调用
- 使用JavaScript对象
注意:if语句、switch语句、变量声明不属于表达式,不能出现在{}中
jsx
const message = 'this is message'
function getAge(){
return 18
}
function App(){
return (
<div>
<h1>this is title</h1>
{/* 字符串识别 */}
{'this is str'}
{/* 变量识别 */}
{message}
{/* 变量识别 */}
{message}
{/* 函数调用 渲染为函数的返回值 */}
{getAge()}
</div>
)
}
- 列表渲染
在JSX中可以使用原生js种的
map方法
实现列表渲染
jsx
const list = [
{id:1001, name:'Vue'},
{id:1002, name: 'React'},
{id:1003, name: 'Angular'}
]
function App(){
return (
<ul>
{list.map(item=><li key={item.id}>{item}</li>)}
</ul>
)
}
- 条件渲染
在React中,可以通过逻辑与运算符&&、三元表达式(?) 实现基础的条件渲染
jsx
const flag = true
const loading = false
function App(){
return (
<>
{flag && <span>this is span</span>}
{loading ? <span>loading...</span>:<span>this is span</span>}
</>
)
}
- 复杂条件渲染
需求:列表中需要根据文章的状态适配
解决方案:自定义函数 + 判断语句
jsx
const type = 1 // 0|1|3
function getArticleJSX(){
if(type === 0){
return <div>1</div>
}else if(type === 1){
return <div>2</div>
}else(type === 3){
return <div>3</div>
}
}
function App(){
return (
<>
{ getArticleJSX() }
</>
)
}
react中定义组件
在React中,一个组件就是首字母大写的函数,内部存放了组件的逻辑和视图UI, 渲染组件只需要把组件当成标签书写即可
- 函数式组件
jsx
var MyComponent = (props) => {
console.log(this); //此处的this是undefined,因为babel编译后开启了严格模式
return <h2>我是一个函数式组件</h2>
}
ReactDOM.render(
<div>
<MyComponent />
</div>,
document.querySelector("#demo")
)
// 1.React解析组件标签,找到了MyComponent组件。
// 2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面中。
- 类组件 ------ ES6 语法
jsx
class MyComponent extends React.Component{
constructor(props){
super(props)
}
render(){
return <h2>我是一个类组件</h2>
}
}
ReactDOM.render(
<div>
<MyComponent />
</div>,
document.querySelector("#demo")
)
注意
- 组件名首字母必须为大写
- 函数返回一个虚拟 DOM 节点
- 类组件必须要有 render 方法
- render 必须返回一个虚拟 DOM 节点
- 虚拟DOM元素只能有一个根元素
- 虚拟DOM元素必须有结束标签
- 实际工作中,类组件是常用的方式

-
组件渲染 ------ 组件子节点
因为组件的调用是将组件当成一个 DOM 节点使用,所以组件里面可以包含子节点。React 对组件的子节点通过 this.props.children 来获取,通常this.props.children会有以下几种情况
-
如果当前组件没有子节点,它就是 undefined
-
如果有一个子节点,数据类型是 object
-
如果有多个子节点,数据类型就是 array
-
为了解决这种数据类型不一致导致在使用的过程中要不断判断的情况,React 提供了一个方法Reacth.Children来处理该属性
jsx
var Component1 = React.createClass({
render: function(){
return (
<div>
{
React.Children.map(this.props.children, function(childNode){
return <li>{childNode}</li>
})
}
</div>
);
}
})
ReactDOM.render(
<Component1>
<span>Tom</span>
<span>Sam</span>
</Component1>, document.getElementById('div1'));