什么是JSX语法
全称JavaScript XML是一种扩展语法, 可以实现在JS代码中直接写HTML的功能. 更直观的说它是 React.createElement(component, props, ...children) 函数的语法糖, 可以在编译时被转换为JavaScript对象.
//实际写的代码
<h1 color="orange"> test data <h1/>
//会被编译成
React.createElement('h1', {color: "orange"}, test data');
特点
- 结构清晰
- 抽象程度高
- 模块化
- 类型安全
高级用法
1. 条件渲染
if/else
class ConditionalRendering extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false, // 修改这个值以测试不同的渲染
};
}
render() {
const { isLoggedIn } = this.state;
if (isLoggedIn) {
return <h1>欢迎回来!</h1>;
} else {
return <h1>请登录.</h1>;
}
}
}
三元运算符
class ConditionalRendering extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false, // 修改这个值以测试不同的渲染
};
}
render() {
const { isLoggedIn } = this.state;
return (
<div>
{isLoggedIn ? <h1>欢迎回来!</h1> : <h1>请登录.</h1>}
</div>
);
}
}
&&运算符
class ConditionalRendering extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false, // 修改这个值以测试不同的渲染
};
}
render() {
const { isLoggedIn } = this.state;
return (
<div>
{isLoggedIn && <h1>欢迎回来!</h1>}
{!isLoggedIn && <h1>请登录.</h1>}
</div>
);
}
}
switch
class ConditionalRendering extends React.Component {
constructor(props) {
super(props);
this.state = {
userRole: 'guest', // 修改这个值以测试不同的渲染
};
}
render() {
const { userRole } = this.state;
let message;
switch (userRole) {
case 'admin':
message = <h1>欢迎,管理员!</h1>;
break;
case 'user':
message = <h1>欢迎,用户!</h1>;
break;
case 'guest':
message = <h1>欢迎,访客!</h1>;
break;
default:
message = <h1>角色未知,请登录.</h1>;
}
return <div>{message}</div>;
}
}
2. 列表渲染
map
class ListRendering extends React.Component {
constructor(props) {
super(props);
this.state = {
items: ['apple', 'banana', 'orange', 'grapes'], // 列表项
};
}
render() {
const { items } = this.state;
return (
<div>
<h1>水果列表</h1>
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li> // 使用 map 方法渲染列表项
))}
</ul>
</div>
);
}
}
filter
class FilteredListRendering extends React.Component {
constructor(props) {
super(props);
this.state = {
items: ['apple', 'banana', 'orange', 'grapes'], // 原始列表
searchTerm: '', // 搜索关键词
};
}
handleInputChange = (event) => {
this.setState({ searchTerm: event.target.value }); // 更新搜索关键词
};
render() {
const { items, searchTerm } = this.state;
// 使用 filter 方法根据搜索关键词过滤列表
const filteredItems = items.filter(item =>
item.includes(searchTerm) // 判断列表项是否包含搜索关键词
);
return (
<div>
<h1>fruit list</h1>
<input
type="text"
placeholder="search fruit"
value={searchTerm}
onChange={this.handleInputChange} // 处理输入变化
/>
<ul>
{filteredItems.map((item, index) => (
<li key={index}>{item}</li> // 渲染过滤后的列表项
))}
</ul>
</div>
);
}
}
key
相当于多了一个唯一标识, 方便追踪对应的元素的状态
import React from 'react';
class KeyListRendering extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [
{ id: 1, name: 'apple' },
{ id: 2, name: 'banana' },
{ id: 3, name: 'orange' },
{ id: 4, name: 'grapes' },
], // 每个项都有唯一的 id
};
}
render() {
const { items } = this.state;
return (
<div>
<h1>fruit list</h1>
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li> // 使用 item.id 作为 key
))}
</ul>
</div>
);
}
}
export default KeyListRendering;
3. props
全称Properties, 用于父子组件之间通信
// 子组件
const FruitItem = ({ name }) => {
return <li>{name}</li>; // 使用 props 渲染水果名称
};
// 父组件
class FruitList extends React.Component {
constructor(props) {
super(props);
this.state = {
fruits: ['apple', 'banana', 'orange', 'grapes'] // 水果列表
};
}
render() {
const { fruits } = this.state;
return (
<div>
<h1>fruits list</h1>
<ul>
{fruits.map((fruit, index) => (
<FruitItem key={index} name={fruit} /> // 将水果名称作为 props 传递给子组件
))}
</ul>
</div>
);
}
}
性能优化
-
React.memo
- 组件的props没有变化时跳过重新渲染,从而提高性能
- 用于缓存复杂函数的计算结果或者构造的值, 返回缓存的结果
-
useCallback
- 是useMemo的语法糖
- 用于缓存函数本身,确保函数的引用在依赖没有改变时保持稳定
-
React.PureComponent
- 对对每个props值进行基本的值对比来决定是否重渲染组件, 对于复杂类型不会遍历每个属性的变化