React 扩展


setState()

  let {count} = this.state;
  
 // react的 setState 是异步执行的 !!!
 // 对象式的 setState
 // 第二个参数是回调函数、在setState() 函数和render()函数执行之后被调用
 // 也就是说在这个回调函数中可以拿到更新后的状态
 setState({count: count + 1}, () => {
 });

 // 函数式的 setState
 // 对象式的 setState 是函数式 setState 的语法糖
 setState((state, props) => {return {count: count + 1}})

lazy 组件懒加载

import React {lazy, Suspense} from "react";
import {Route} from "react-router-dom";

// 假设懒加载的组件为 Home 组件
// 传统的引入方式
import Home from "./Home/index";

// 懒加载的引入方式
const Home = lazy(() => import("./Home/index"));

// 开启组件懒加载
// fallback 路由组件加载过程中的展示组件 该组件不支持懒加载
<Suspense fallback={<h1>loading...</h1>}>
	{/*注册路由*/}
	<Route path="/home" component={Home}/>
</Suspense>

Hooks

# React Hooks 是什么?
- Hooks 是 React 16.8版本新增的特性
- 可以让你在函数式组件中中使用 state 以及其他的 React 特性

# 三个常用的 Hooks
- State Hook: React.useState()
- Effect Hook: React.useEffect()
- Ref Hook: React.useRef()


useState

export default Demo() {
	// useState() 返回一个数组 count 为  初始状态 0
	// setCount 为修改状态的函数 一个状态 对应一个修改状态的函数
	/* setCount((newCount) => {return {count : newCount}}) */
	const [count, setCount] = React.useState(0);
	
	function add() {
		// 第一种写法
		setCount(count + 1);
		// 第二种写法
		setCount((count) => {return count + 1});
	}
	
	
	return (
		<div>
			<h2>当前的求和为 {count}</h2>
			<button onClick={add}>点击+1</button>
		</div>
	)
}

useEffect

function Demo() {
	const [count, setCount] = React.useState(0);

	// useEffect() 在Demo方法第一次调用后执行
	// useEffect() 的第二个参数为要监听的状态 如果为空数组 就相当于 didmount;
	// 如果第二个参数为 [count] 即监听 count 状态的改变
	// count 状态一改变、就执行回调函数
	React.useEffect(() => {
		setCount(count + 1)return () => {
			// 返回的函数相当于类式组件的 willunmount;
		}
	}, []);
	
}

useRef

function Demo() {
	const myRef = React.useRef();

	
	return (
		<div>
			{/*获得input 框的 value myRef.current.value*/}
			<input type="text" ref={myRef}/>
		</div>
	)
}

Fragment

import React {Fragment} from "react";

function Demo() {
	return (
		<Fragment>
			{/* Fragment 相当于 <> </> 但是 Fragment 可以有属性值 比如 key = {} */}
			{/* 但是 <></> 标签不能有任何属性值 */}
		</Fragment>
	)
}

Content
# 组件间的通信方式


const MyContext = React.createContent();
const {Provider} = MyContext;

export default class A extends Component {
	state = {username : "tom"}
	
	render() {
		return (
			<div>
				<Provider value={this.state.username}>
					<B></B>
				</Provider>
			</div>
		)
	}
}

class B extends Component {

	// 声明接受context
	static contextType = MyContext;
	render() {
		return (
			<div>
				{this.context}
			</div>
		)
	}
}

# 注意:在应用的开发中 我们一般不使用 context 而是使用 封装好的 React 插件

组件优化

# Component 的两个问题
- 只要执行 setState() 即使不改变状态数据 组件也会重新render()
- 只要当前组件重新 render() 就会自动更新 render 的子组件 *效率低*

# 效率高的做法
- 只有当组件的状态或属性发生变化时才重新 render()

# 原因
- component 的 shouldComponentUpdate() 总是返回 true

# 解决
## 方法一
- 重写 shouldComponentUpdate() 方法
- 比较新旧 state props 数据 如果有变化才返回 true 如果没有返回 false

## 方法二
- 继承 PureComponent
- PureComponent 重写了 shouldComponentUpdate() 
- 只有 state 和 props 数据有变化 才返回 true

## 注意:
- 方法二只是进行 state 和 props 的地址比较 如果只是对象内部的数据变了 返回 false !!!
- 不要直接修改 state 数据 而是**产生**新数据 !!

## 实际项目开发中一般使用方法二进行组件优化

renderProps 插槽

export default class Parent extends Component {

	render() {
		<div>
			<A render={(name) => <B name={name}/>}>
		</div>
	}
}

class A extends Component {
	render() {
		let {name} = this.state;
		let {render} this.props;
		return (
			<>
				{render(name)}
			</>
		}
	}

}

错误边界

export default class Parent extends Component {
	
	// 用于标识子组件是否产生错误
	state = {hasError: ""}
	
	// 当 Parent 的子组件出现错误时、会触发此函数的执行、并携带错误信息
	static getDerivedStateFromError(error) {
		return {hasError: error};
	}

	// 该生命周期钩子函数用于在组件出现错误时执行
	// 向后台发送出现错误的消息和次数
	componentDidCatch() {
	}
	
	render() {
		return (
			<>
				{this.state.hasError ? "当前网络不稳定" : <A/>}
			</>
		)
	}

}


未完待续…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值