useReducer
const [state, disptach] = useReducer(reducer, initialArg, init);
Accepts a reducer of type (state, action) => newState, and returns the current paired with a disptach method.
useReducer is usually preferable to useState when you have complex state logic that involves sub-values or when the next state depends on the previous one. useReducer also lets you optimize performance for components that trigger deep updates.
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>
</>
);
}
Lazy initialization
function init(initialCount) {
return {count: initialCount};
}
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
case 'reset':
return init(action.payload);
default:
throw new Error();
}
}
function Count({initialCount}) {
const [state, dispatch] = useReducer(reducer, initialCount, init);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'reset', payload: initialCount})}>
Reset
</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
useCallback
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b]
)
useCallback(fn, deps) is equivalent to useMemo(() => fn, deps)
返回一个函数,只有在依赖项发生的时候才会更新(返回一个新的函数)
useMemo
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])
The function passed to useMemo runs during rendering. For example, side effects belong in useEffect, not useMemo.
useRef
const refContainer = useRef(initialValue);
useRef returns a mutable ref object whose .current property is initialized to the passed argument(initialValue). The returned object will persist for the full lifetime of the component.
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
useImperativeHandle
useImperativeHandle(ref, createHandle, [dep])
useImperativeHandle customizes the instance value that is exposed to parent components when using ref.
/*
In this exmple, a parent component that renders <FancyInput ref={inputRef} /> would be able to call inputRef.current.focus().
*/
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} ... />
}
//useImperativeHandle should be used with forwardRef
FancyInput = forwardRef(FancyInput);
useLayoutEffect
The signature is identical to useEffect, but it fires synchronously after all DOM mutations. Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.
useDebugValue
useDebugValue(value)
useDebugValue can be used to display a label for custom hooks in React DevTools.
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
// Show a label in DevTools next to this Hook
// e.g. "FriendStatus: Online"
useDebugValue(isOnline ? 'Online' : 'Offline');
return isOnline;
}
Defer formatting debug values
useDebugValue accepts a formatting function as an optional second parameter. The function is only called if the Hooks are inspected.
useDebugValue(date, date => date.toDateString())
网友评论