TypeScript and React: Hooks
阿新 • • 發佈:2020-12-08
Hooks以前將“無狀態”功能元件放到了……基本上,傳統類元件都可以做到。使用更乾淨的API!在React 16.7中釋出後不久,DefinitelyTyped中的React型別也得到了更新。瞭解如何在TypeScript中使用鉤子!
useState
import React, { FunctionComponent, useState } from 'react'; const Counter:FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => { const [clicks, setClicks] = useState(initial); return <> <p>Clicks: {clicks}</p> <button onClick={() => setClicks(clicks+1)}>+</button> <button onClick={() => setClicks(clicks-1)}>-</button> </> }
useEffect
useEffect在這裡有所有副作用。新增事件偵聽器,更改文件中的內容,獲取資料。一切你所使用的(元件生命週期方法componentDidUpdate
,componentDidMount
,componentWillUnmount
)的方法簽名是非常簡單的。它接受兩個引數:
- 無需任何引數即可呼叫的函式。這是您要呼叫的副作用。
- 型別的值陣列any。此引數是可選的。如果不提供,則每次元件更新時都會呼叫提供的功能。如果這樣做,React將檢查這些值是否確實發生了變化,並且僅在存在差異時才觸發函式。
useEffect(() => { const handler = () => { document.title = window.width; } window.addEventListener('resize', handler); return true; return () => { window.removeEventListener('resize', handler); } })
useContext
useContext允許您從元件中的任何位置訪問上下文屬性。非常類似於Context.Consumer 類元件中的do。型別推斷在這裡非常出色,您不需要使用任何TypeScript特定的語言功能就可以完成所有工作:
import React, { useContext } from 'react'; export const LanguageContext = React.createContext({ lang: 'en' }); const Display = () => { const { lang } = useContext(LanguageContext); return <> <p>Your selected language: {lang}</p> </> }
useRef
function TextInputWithFocusButton() {
const inputEl = useRef<HTMLInputElement>(null);
const onButtonClick = () => {
if(inputEl && inputEl.current) {
inputEl.current.focus();
}
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
useMemo-useCallback
您知道useEffect,可以通過向其傳遞一些引數來影響某些函式的執行。React檢查這些引數是否已更改,並且僅在存在差異的情況下才會執行此功能。
useMemo做類似的事情。假設您有大量計算方法,並且只想在其引數更改時執行它們,而不是每次元件更新時都執行它們。useMemo返回記憶的結果,並且僅在引數更改時才執行回撥函式。
function getHistogram(image: ImageData): number[] {
...
return histogram;
}
function Histogram() {
...
const histogram = useMemo(() => getHistogram(imageData), [imageData]);
}
useCallback非常相似。實際上,這也是可以表達的捷徑useMemo。但是它返回一個回撥函式,而不是一個值。
const memoCallback = useCallback((a: number) => {
// doSomething
}, [a])
useReducer
type ActionType = {
type: 'reset' | 'decrement' | 'increment'
}
const initialState = { count: 0 };
// We only need to set the type here ...
function reducer(state, action: ActionType) {
switch (action.type) {
// ... to make sure that we don't have any other strings here ...
case 'reset':
return initialState;
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
function Counter({ initialCount = 0 }) {
const [state, dispatch] = useReducer(reducer, { count: initialCount });
return (
<>
Count: {state.count}
{ /* and can dispatch certain events here */ }
<button onClick={() => dispatch({ type: 'reset' })}>
Reset
</button>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</>
);
}