函数组件下,配合Hook的使用可以达到类似class组件的效果,并且hook可以更好的进行逻辑复用。
useState
count为状态(变量),只能使用setCount对其修改。
import React, { useState } from 'react'
function example(props) {
const [count, setCount] = useState(0) // 初始值0
return (
<div>
{ count }
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
)
}
useEffect
import React, { useState, useEffect,} from 'react';
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffetc(() => {}, []) // 只在挂载时执行
useEffect(() => {}, [count]) // 只在挂载和count改变时执行
useEffect(() => {}) // 在挂载和数据更新时执行
useEffect
可以返回一个函数来清除副作用
组件挂载时,运行副作用(effect);组件更新时,先清除上一个effect,再运行下一个effect;组件卸载时,清除最后一个effect(常用于订阅)
useEffect
使用时需要注意闭包理解
useEffect(() => {
// 运行副作用
ChatAPI.subscribe()
// 清除副作用
return () => {
ChatAPI.unsubscribe()
}
})
useRef
在函数组件中引入ref,ref可用于保存变量
import React, { useRef } from 'react'
function App(props) {
let refs = useRef(null)
return (
<input ref={refs}>
)
}
useReducer
useState
的替代方案,类似redex,使用action进行对应操作更改数据。
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
useMemo
把“创建”函数和依赖项数组作为参数传入 useMemo
,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算。
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
useCallback
类似useMemo,把内联回调函数及依赖项数组作为参数传入 useCallback
,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新。
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);