React笔记(七)
2024 年 5 月 3 日 星期五(已编辑)
/
7
摘要
这篇文章介绍了React中常用的Hooks和一些相关概念,包括useReducer、useMemo、React.memo、useCallback、React.forwardRef、useImperativeHandle、Class组件、生命周期函数、组件通信、zustand等内容。每个部分都有相应的代码示例和解释。
这篇文章上次修改于 2024 年 5 月 7 日 星期二,可能部分内容已经不适用,如有疑问可询问作者。
阅读此文章之前,你可能需要首先阅读以下的文章才能更好的理解上下文。
1.useReducer
和useState作用类似,用于管理相对复杂的状态数据
//1.定义一个reducer函数(根据不同的action返回不同的状态)
function reducer(state,action) {
switch(action.type){
casse 'INC':
return state+1
case 'DEC':
return state-1
default:
return state
}
}
//2.在组件中调用useReducer,并传入reducer函数和状态初始值
const [state,dispatch] = useReducer(reducer,0)
//3.通过dispatch传入一个action对象
dispatch({
type: 'INC'
})
//分派action时传参
dispatch({
type: 'SET',
payload: 100
})
function reducer (state, action){
switch(action.type){
case 'INC':
return state+1
case 'DEC':
return state-1
case 'SET':
return action.payload
default:
return state
}
}
2.useMemo
在组件每次重新渲染的时候缓存计算的结果,缓存消耗非常大时候使用
useMemo(() => {
//根据count返回计算的结果
},[count])
3.React.memo
允许组件在Props没有改变的情况下跳过渲染,React组件默认父组件重新渲染时候,子组件也会随之重新渲染
//只有在Props改变时候才会重新渲染
const MemoComponet = memo(function SomeComponent(props){
//...子组件内容
})
4.React.memo-props的比较机制
在memo缓存组件之前,React会对每一个prop使用Object.is比较新值和老值,返回true,表示没有变化
//prop是简单类型
Object.is(3,3) => true (没有变化)
//prop是引用类型 (对象/数组)
Object([],[]) => false (有变化,React只关心引用是否改变)
//保证引用稳定 -- useMemo
const list = useMemo(() => {
return [1,2,3]
},[])
5.useCallback
作用:在组件多次渲染时候缓存函数(引用类型),使用useCallback包裹函数以后跨域保证重新渲染时候保持稳定
const Input = meme(function Input ({ onChange }) {
console.log('子组件重新渲染')
return <input type='text' onChange={(e) => onChange(e.target.value)}></input>
})
function App(){
//传给子组件的函数
const changeHandler = useCallback((value) => console.log(value),[])
const [count,setCount] = useState(0)
return (
<div>
{/*把函数作为prop传给子组件*/}
<Input onChange={changeHandler} />
<button onClick={() => setCount(count+1)}>
{count}
</button>
</div>
)
}
6.React.forwardRef
父组件通过ref获取子组件内部的input元素使其聚焦
//子组件
const Input = forwardRef((props,ref) => {
return <input type='text' ref={ref}/>
})
//父组件
function App() {
const inputRef = useRef(null)
return (
<div>
<Input ref={inputRef}/>
</div>
)
}
7.useInperativeHandle
父组件通过ref调用子组件内部的focus方法实现聚焦
//子组件
const Input = forwadRef((props,ref) => {
const inputRef = useRef(null)
//实现聚焦路径函数
const foucuHandler = () => {
inputRef.current.foucs()
}
//暴露函数给父组件
useImperativeHandle(ref,() => {
return {
foucsHandler
}
})
return <input type='text' ref={inputRef}/>
}
//父组件
function App() {
const sonRef = useRef(null)
const foucsHand;er = () => {
sonRef.current.foucsHandler()
}
return (
<div>
<Input ref={inputRef}/>
<button onClick={foucsHandler}>foucs</button>
</div>
)
}
8.Class类组件(Class API)
通过JS中的类来组织代码,老版本项目中喜欢用,现在已经不推荐
//1.通过类属性state定义状态数据
//2.通过setState方法修改数据
//3.如果render来写UI模板(JSX)
class Counter extends Component {
//定义状态变量
state = {
count: 0
}
//事件回调
clickHandler = () => {
this.setState({
count: this.state.count + 1
})
//事件回调(JSX)
render () {
return <button onClick={this.clickHandler}>{this.state.count}</button>
}
}
9.类组件生命周期函数
组件从创建到销毁的各个阶段自动执行的函数
//1.componentDidMount:组件挂载完毕自动执行 -异步数据获取
//2.componentWillUnmount:组件卸载时自动执行--清理副作用
10.类组件通信
//1.父传子:通过prop绑定数据
class Son extends Componet {
render() {
return <div>我是子组件{this.props.msg}</div>
}
}
class Parent extends Component {
state = {
msg: 'this is parent msg'
}
render() {
return <div>我是父组件<Son msg={this.state.msg}/></div>
}
}
//2.子传父:通过prop绑定父组件的函数,子组件调用
class Son extends Componet {
render() {
return <div>我是子组件{this.props.msg}</div>
<button onClick={()=>this.props.onGetSonMsg('this is son msg')}></button>
}
}
class Parent extends Component {
state = {
msg: 'this is parent msg'
}
getSonMsg = (sonMsg) => {
console.log(sonMsg)
}
render() {
return <div>我是父组件<Son msg={this.state.msg} onGetSonMsg={this.getSonMsg}/></div>
}
}
//3.兄弟通信:状态提升,通过父组件桥接
11.zustand
状态管理工具类似于Redux
//1.创建store
//2.函数参数必须返回一个对象,对象内部编写状态数据和方法
//3.set是用来修改数据的专门方法必须调用它来修改函数
//语法1:参数是函数 需要用到原来的数据计算
//语法2:参数是对象set({count:100})
import { create } from 'zustand'
const store = create((set) => {
return {
//状态数据
count: 0,
//修改状态数据的方法
inc: () -> {
set((state) => ({count: state.count + 1}))
}
}
})
...
const [count, inc] = store()
zustand-异步支持
const Store = create((set) => {
return {
//状态数据
channeList: [],
//异步方法
fetchGetList: async () => {
const res = await fetch(URL)
const jsonData = await res.json()
//调用set方法更新状态
set({
channelList: jsonData.data.channalist
})
}
}
})
...
const { channeList,fetchGetList } = Store()
zustand-切片模式,,当单个store比较大的时候,跨域采用切片模式进行模块拆分组合
//组合切片
const useStore = create((...a) => {
...Store(...a),
...store(...a)
})