常用hooks
useState
组件状态管理钩子,存储和修改状态
useState 使函数组件能够使用state
let [count, setCount] = useState(100);
state 是要设置的状态
setState 是更新 state 的方法,只是一个方法名,可以随意修改。
initState 是初始的 state,可以是随意的数据,也可以是回调函数,但是函数必须是有返回值。
const App=()=>{
const [count, setCount] = useState(0);
return (
<div>
<div>点击了{count} 次</div>
<Button onClick={() => { setCount(count + 1) }}>点击</Button>
</div>
)
}
useEffect
useEffect 是 componentDidMount(组件挂载完成时触发)、componentDidUpdate(状态改变时触发)、componentWillUnmount(组件将要卸载时触发)这几个生命周期方法的统一。
useEffect(callback, array)
callback:回调函数,作用是处理副作用逻辑
callback 可以返回一个函数,用作清理
array(可选参数):数组,用于控制 useEffect 的执行
分三种情况空数组,则只会执行一次(即初次渲染 render ),相当于 componentDidMount。
非空数组,useEffect 会在数组发生改变时执行。
不填 array 这个数组,useEffect每次渲染都会执行。
useEffect(()=>{
// 副作用逻辑
return ()=>{
// 清理副作用需要清理的内容
// 类似于 componentWillUnmount
}
}, [])
数组为空,return里的在组件卸载时调用 数组里有值,依赖性更新时,return里的会调用
function HooksTest() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`您点击了${ count }次按钮`)
return () => {
console.log('组件卸载或者更新了')
}
}, [count])
return (
<div>
<div>你点击了{count}次</div>
<Button onClick={() => { setCount(count + 1) }}>点击</Button>
</div>
)
}
useMemo useMemo 的用法类似 useEffect,常常用于缓存一些复杂计算的结果。useMemo 接收一个函数和依赖数组,当数组中依赖项变化的时候,这个函数就会执行,返回新的值。
因为useMemo缓存的是一个值,所以初始化的时候useMemo里的callback会自动调用一次
const memoValue = useMemo(callBack, array);
callback 是一个函数用于处理逻辑
array 是控制 useMemo 重新执行的数组, array 改变时才会重新执行 useMemo
useMemo 返回的是一个记忆值,是 callback 的返回值
function HooksTest() {
const [num1, setNum1] = useState(0)
const [num2, setNum2] = useState(99)
return (
<>
<button onClick={() => setNum1(num1+1)}>name</button>
<button onClick={() => setNum2(num2-1)}>content</button>
<Son num1={num1}></Son>
</>
)
}
function Son({num1}) {
const changeNum = (num) => {
console.log('11')
return num + '------'
}
//不使用useMemo的情况下,父组件num2改变这里也会调用 父组件更新子组件跟着更新
// const num=changeName(num1)
//这个时候我们点击 改变num2值的按钮,发现changeName 并没有被调用。
//但是点击改变num1值按钮的时候,changeName被调用了。我们可以使用useMemo方法 避免无用方法的调用,当然一般我们changName里面可能会使用useState来改变state的值,那是不是就避免了组件的二次渲染。达到了优化性能的目的
const num = useMemo(() => changeNum(num1), [num1])
return (
<div>
<div>{num}</div>
</div>
)
}
export default Son;
useCallBack() useCallback和 useMemo一样,也是用于性能优化,但它返回的是缓存的函数
使用方法如下:
const callback=useCallBack(callBack, array);
useCallback会将我们传递给它的函数callBack返回,并且将这个结果缓存;当依赖array变更时,会返回新的函数
const set =new Set()
function HooksTest() {
const [count, setCount] = useState(1);
const [val, setVal] = useState('');
const callback = useCallback(() => {
console.log({count});
}, [count]);
set.add(callback);
return <div>
<h4>{count}</h4>
<h4>{set.size}</h4>
<div>
<button onClick={() => setCount(count + 1)}>+</button>
<input value={val} onChange={event => setVal(event.target.value)}/>
</div>
<Son callback={callback} />
</div>;
}
function Son({callback}) {
const [count, setCount] = useState(() => callback());
useEffect(() => {
setCount(callback());
console.log('------')
}, [callback]);
return <div>
{count}
</div>
}
我们可以看到,每次修改count,set.size就会+1,这说明useCallback依赖变量count,count变更时会返回新的函数;而val变更时,set.size不会变,说明返回的是缓存的旧版本函数
useRef
useRef变化不会主动使页面渲染
function HooksTest() {
const r = useRef(0);
console.log(r);
const add = () => {
r.current += 1;
console.log(`r.current:${r.current}`);
};
return (
<div className="App">
<h1>r的current:{r.current}</h1> <button onClick={add}>点击+1</button>
</div>);
}
注意事项
警告:React Hook useEffect has a missing dependency: ‘click‘
在使用useEffect时,当我们将函数的声明放在useEffect函数外面时,会报eslint警告
解决:将函数放在useEffect里面
useEffect(()=>{
function Test(){
}
Test()
},[])
使用 // eslint-disable-line react-hooks/exhaustive-deps**
useEffect(() => {
clickshow()
}, [showConfirmation])// eslint-disable-line react-hooks/exhaustive-deps
function clickshow(){
...
}