学习代码来源b站尚硅谷视频。
hooks的概念这里也不解释了。
hooks stateHook
在hooks中使用state
import React from 'react'
function Demo() {
// 函数开启严格模式this指向为undefined,所以需要react提供api
const [count, setCount] = React.useState(0) // useState输入一个初始值,返回一个数组,第一个元素为react底层帮你储存的state值,第二个为修改该state的方法
console.log(count, setCount);
function add() {
setCount(count + 1)
}
return (
<div>
<h2>当前求和为:{count}</h2>
<button onClick={add}>点我加1</button>
</div>
)
}
export default Demo
每次点击加1函数都会重新执行一遍,count变量并不会重置,因为react能够帮你存储,所以每次函数执行的时候都是拿到的上一次函数执行的值。
useEffect个人的理解是,一个函数集合了监听,和三个生命周期钩子(componentDidMount 、componentDidUpdata 、componentDidUnmount)的能力。
...
const [count] = React.useState(0)
React.useEffect(() => {
console.log('componentDidMount的执行');
console.log('state的监听触发componentDidUpdata的执行', count);
return () => { // 返回一个函数,功能为componentDidUnmount的钩子
console.log('我要被卸载了');
}
}, [count])
// 参数二表示要监听哪些state,是一个数组。传空数组表示监听所有state,可以直接当成componentDidMount钩子使用,下面是简写
React.useEffect(() => {
console.log('componentDidMount的执行');
}, [])
...
useRef
就是获取实例dom
...
const myRef = React.useRef()
function show() {
alert(myRef.current.value) // 这样就能拿到dom了
}
...
<input type="text" ref={myRef} />
...
路由相关hooks
【react框架】学习记录12-React Router 6的学习使用记录
Fragment
jsx标签必须返回一个根元素,但有时候并不像渲染一个多余的根元素就可以使用这个,原理类似vue的template标签
<Fragment>
<img />
<img />
Fragment>
还能在遍历中绑定key值,但有且仅有一个key属性
<Fragment key={xxxxxx}>
<img />
<img />
Fragment>
如果不需要绑定key还有个超级简写的方法
<>
<img />
<img />
</>
PureComponent
在平时写组件时,对于祖父组件和后代组件的更新机制有这样的问题:
父组件修改了子组件没用到的state数据,父组件的render会重新执行一遍,导致子组件做了多余的更新,例如this.setState ({})
同理孙组件也一样会被父组件影响,因为子组件更新了,所以同样做了多余的更新。
react提供了shouldComponentUpdate这个api让我们手动去控制什么情况下需要调用render函数:
shouldComponentUpdate(newState, newProps) {
// 入参能获取到更新后的state和props
return true // 返回true则执行render,不返回则不执行render
}
父组件通过新旧的state对比去看要不要执行render,子组件可以通过新旧的props对比去看要不要执行render。
但每次都要在每个组件手动去优化更新机制太过麻烦,所以react提供了PureComponent:
import React, { PureComponent } from 'react' // 就是把PureComponent代替掉Component
export default class App extends PureComponent {
...
}
原理就是react在底层机制已经通过shouldComponentUpdate去帮我们处理好(比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false),子孙组件需不需要更新。但有一个唯一的缺点就是,父组件更新state的时候,需要传入的是一新的变量,因为react会对传入的变量与原来的state里的数据做一个浅比较,如果是同一个引用堆内存的地址,就不会更新所有组件:
state = { a: 1 }
...
fn = () => {
state = this.state
state.a = 2
this.setState(state) // 不会更新render
}
fn = () => {
state = this.state
state.a = 2
this.setState({...state}) // 才会更新render
}
错误边界
当有一个子组件出现js报错问题,父组件会在页面上直接渲染不出来,这在生产环境上会给用户带来不好的体验。
react提供了错误处理相关的api,能够让项目在生产环境中,不会因为一个子组件的报错而影响父级组件的显示。
// 在父组件中
state = {hasError: false}
static getDerivedStateFromError(error) { // 捕获生命周期和render调用时,发生的错误
console.log(error); // 在render之前触发
// 返回新的state
return {
hasError: true,
};
}
componentDidCatch(error, info) {
// 统计页面的错误。发送请求发送到后台去,为了日后修改bug
console.log(error, info);
}
// 然后在渲染的时候,如果子组件出错,就用个标签替换一下
render() {
return (
<div>
{this.state.hasError ? <h1>网络出错了</h2> : <Child />}
</div>
)
}
注意:这个功能只有在生产环境中会触发,在开发环境中,该报错还是会报错。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)