1. 什么是 Hook?
Hook 就是一个特殊的函数。
在React中只有两个地方可以使用Hook:
2. useState
useState Hook就是让函数式组件保存自己状态的函数。
const [numState,setNumState] = useState(10)
<div>
<p>{numState}</p>
<button onClick={() =>{setNumState(numState+1)}}>+</button>
</div>
3. useEffect
useEffect Hook可以看做(组件挂载,组件更新,组件即将卸载)三个生命周期函数的组合。
特点:可以设置依赖,只有依赖发生变化的时候才执行。
优势: 1. 默认情况下只要数据发生变化就会调用。
2. 对比类组件生命周期方法优势:易于拆分。
function Child() {
return <div>Child子组件</div>;
}
export default function UseEffect() {
const [showState,setShowState] = useState(true)
useEffect(() =>{
console.log('修改DOM');
})
useEffect(() =>{
console.log('注册监听');
return () =>{
console.log('移出监听');
}
})
useEffect(() =>{
console.log('发送网络请求');
})
return (
<div>
{showState && <Child />}
<button onClick={() =>{setShowState(!showState)}}>切换</button>
</div>
);
}
4. useContext
useContext Hook是给函数式组件提供数据共享的函数
import React, { createContext, useContext } from "react";
const UserContext = createContext({});
const ColorContext = createContext({});
function Child() {
const user = useContext(UserContext);
const color = useContext(ColorContext);
return (
<div>
<p>Child子组件</p>
<p>{user.name}</p>
<p>{user.age}</p>
<p>{color.color}</p>
</div>
)
}
export default function UseContext() {
return (
<div>
{/* 父组件通过 Provider(生产数据) */}
<UserContext.Provider value={{ name: "liu", age: 24 }}>
<ColorContext.Provider value={{ color: "red" }}>
<Child />
</ColorContext.Provider>
</UserContext.Provider>
</div>
);
}
5. useReducer
useReducer Hook是useState的一种替代方案,可以复用操作数据的逻辑代码。
注意点:不是用来替代Redux的。
import React, { useReducer, useState } from 'react';
function reducer(state,action) {
switch(action.type) {
case 'ADD':
return {...state,num: state.num + 1}
case 'SUB':
return {...state,num: state.num + 1}
default:
return state
}
}
function Child1() {
const [state,dispatch] = useReducer(reducer,{num: 10})
return (
<div>
<p>Child1子组件</p>
<p>{state.num}</p>
<button onClick={() =>{dispatch({type: 'ADD'})}}>+</button>
<button onClick={() =>{dispatch({type: 'SUB'})}}>-</button>
{/* <button onClick={() =>{setNumState(numState+1)}}>+</button>
<p>{numState}</p>
<button onClick={() =>{setNumState(numState-1)}}>-</button> */}
</div>
)
}
function Child2() {
const [state,dispatch] = useReducer(reducer,{num: 20})
return (
<div>
<p>Child2子组件</p>
<p>{state.num}</p>
<button onClick={() =>{dispatch({type: 'ADD'})}}>+</button>
<button onClick={() =>{dispatch({type: 'SUB'})}}>-</button>
{/* <button onClick={() =>{setNumState(numState+1)}}>+</button>
<p>{numState}</p>
<button onClick={() =>{setNumState(numState-1)}}>-</button> */}
</div>
)
}
export default function UseReducer() {
return (
<div>
<Child1/>
<hr />
<Child2/>
</div>
)
}
6. useCallback
useCallback Hook用于优化代码,可以让对应的函数只有在依赖发生变化时重新定义。
只要依赖没有发生变化,那么useCallback返回的永远都是同一个函数。
useCallback底层是利用useMemo实现的。
function useCallback(fn,arr){
return useMemo(() =>{
return fn
},arr)
}
useCallback和useMemo的区别:
1. useCallback返回的永远都是一个函数
2. useMemo返回的是return返回的内容
import React, { memo, useCallback, useState } from 'react';
function Child1(props) {
console.log('Child1组件',props);
return (
<div>
<p>Child1组件</p>
<button onClick={() =>{props.add()}}>+</button>
</div>
)
}
function Child2(props) {
console.log('Child2组件',props);
return (
<div>
<p>Child2组件</p>
<button onClick={() =>{props.min()}}>-</button>
</div>
)
}
const MemoChila1 = memo(Child1)
const MemoChild2 = memo(Child2)
export default function UseCallback() {
const [numState,setNumState] = useState(10)
const [countState,setCountState] = useState(20)
function add() {
setNumState(numState+1)
}
const min = useCallback(() =>{
setCountState(countState-1)
},[countState])
console.log('UseCallback组件');
return (
<div>
<MemoChila1 add={add}/>
<hr />
<MemoChild2 min={min}/>
<hr />
<p>UseCallback组件</p>
<p>{numState}</p>
<p>{countState}</p>
{/* <button onClick={() =>{setNumState(numState+1)}}>+</button> */}
{/* <button onClick={() =>{setCountState(countState-1)}}>-</button> */}
</div>
)
}
7. useMemo
useMemo Hook用于优化代码,可以让对应的函数只有在发生依赖变化时才返回新的值。
useMemo Hook对耗时耗性能函数进行优化。
useCallback和useMemo的区别:
1. useCallback返回的永远都是一个函数
2. useMemo返回的是return返回的内容
3. useMemo
const add = useMemo(() =>{
return () =>{
setNumState(numState+1)
}
},[numState])
const user = {name: 'liu',age: 24}
const user = useMemo(() =>{
return {name: 'liu',age: 24}
},[])
function fn() {
console.log('fn函数');
let total = 0
for (let i = 0; i < 100; i++) {
total += i
}
return total
}
const total = useMemo(() =>{
return fn()
},[])