предисловие
учитесь во мнеtypescriptКогда, как вreactиспользуется вtypescriptПри написании кода неудобно начинать с нуля, потому что официальная документация не используетсяtypescriptБольшинство учебных пособий вы ищете в Интернете самостоятельно, и вы можете найти определение самостоятельно.
Итак, сегодня я подытожу и обобщу то, что использовал, надеясь помочь студентам, которые также изучают
следующий кодreactВерсия16.13.1,существуетcreate-react-appофициальныйtypescriptВ шаблоне нет ошибок
Введите бриф
НемногоReactвстроенный тип
-
React.ReactElement-- использоватьReact.createElementСоздан, можно просто понять какReactсерединаJSXЭлементы -
React.ReactNode——<div>xxx</div>Легальные типы xxx -
React.CSSProperties- встроенный компонентstyleтип объекта -
React.RefObject——React.createRefСозданный тип, доступный только для чтения и неизменяемый -
React.MutableRefObject——useRefСозданный тип, можно изменить - ...
объявление компонента
Объявления компонентов делятся на компоненты класса и компоненты функций.
компонент класса
Определения, используемые компонентами класса, в основномReact.Component<P,S>а такжеReact.PureComponent<P,S,SS>
interface AppProps {
value: string;
}
interface AppState {
count: number;
}
class App extends React.Component<AppProps, AppState> {
static defaultProps = {
value: "",
};
state = {
count: 0,
};
}
React.Component<P,S>здесьPдаpropsтип,Sдаstateтип, который можно записать какReact.Component<AppProp>,потому чтоstateТип будет выведен сам
наверхуPureComponentесть еще одноSS,этоSSдаgetSnapshotBeforeUpdateВозвращаемое значение
функциональный компонент
Есть два способа определить функциональные компоненты.React.FC, нужно напрямую датьpropsнапишите определение
interface AppProps {
value?: string;
}
const App: React.FC<AppProps> = ({ value = '', children }) => {
// ...
};
React.FCозначаетFunctionComponent, если использоватьReact.FC, который уже указан в определенииchildrenТип и возвращаемое значение функции, поэтому вы можете напрямую использоватьchildren
Если это прямоpropsНапишите определение, вам нужно определить его самостоятельноchildrenтип
interface AppProps {
value?: string;
children?: React.ReactNode; // 自己定义children的类型
}
function App({ value = "", children }: AppProps) {
return <>{children}</>;
}
использоватьfunctionПреимущество определения вместо стрелочных функций заключается в том, что вы можете использовать общие компоненты
Заявление о крючках
hooksзаявление, если вы не знаете, как использоватьtsОпределение можно напрямую щелкнуть, чтобы увидеть
useState
useStateВы можете использовать общую передачу параметров или автоматический вывод
const [state, setState] = useState(''); // state的类型为string,自动推断
const [state, setState] = useState<string>(); // state的类型为 string | undefined
// 给初值
const [state, setState] = useState<string | null>(null); // state的类型为 string | null
useRef
useRefТакже делает вывод автоматически
const ref = useRef(""); // ref.current的类型为 string
// 泛型
type Value = { value: string };
const ref = useRef<Value>({ value: "" });
// ref为html元素
const ref = useRef<HTMLDivElement>(null);
return <div ref={ref} />;
Следует отметить, что еслиrefявляется элементом, то начальное значение записывается какnullне будет сообщать об ошибках
useReducer
useReducerУсловно говоря, есть еще что написать, и это может быть автоматически выведено, поэтому нет необходимости вручную писать общие типы (на самом деле, я не знаю, как писать Orz вручную)
// state类型
interface ReducerState {
value: string;
}
// action类型
interface AnyAction {
type: string;
[key: string]: any;
}
// reducer函数
const reducer: React.Reducer<ReducerState, AnyAction> = (state, action) => {
switch (action.type) {
default:
return state;
}
};
// 初始值
const initialState: ReducerState = { value: "" };
const [state, dispatch] = useReducer(reducer, initialState);
// state 的类型为 ReducerState
// dispatch 的类型为 React.Dispatch<AnyAction>
Actionможет быть несколько разныхActionтип союза
useImperativeHandle
useImperativeHandleЭтот хук может передавать внутренние методы черезrefвыставлено, сtsТакже необходимо написать немного больше, и типы должны быть четко обозначены
Поэтому вам нужно использоватьReact.forwardRef, вы можете сначала увидеть следующий раздел
// props
interface AppProps {
value: string;
}
// useImperativeHandle获取到ref的类型
interface Handle {
get: () => string;
}
const App = React.forwardRef<Handle, AppProps>(({ value }, ref) => {
// 定义
useImperativeHandle(ref, () => ({
get: () => `handle get value : ${value}`,
}));
return null;
});
// 使用
const handleRef = useRef<Handle>(null);
// handleRef.current?.get();
return <App value="hello" ref={handleRef} />;
Пользовательские крючки должны обратить внимание на
Есть следующие крючки
const useCustomHook = () => {
const [state, setState] = useState("");
const set = (value: string) => {
if (!value) return;
setState(value);
};
return [state, set];
};
// 使用
const [state, setState] = useCustomHook();
setState('hello') // This expression is not callabl
Пользовательские хуки также должны определять возвращаемые значения.
- const useCustomHook = () => {
+ const useCustomHook = (): [string, (value: string) => void] => {
React.forwardRef
React.forwardRef<T, P = {}>просто пройтиpropsтип иrefтипа, первыйTдаrefтип,Pдаpropsтип
const App = React.forwardRef<HTMLDivElement, AppProps>(({ value }, ref) => {
return <div ref={ref} />;
});
// 使用
const ref = useRef<HTMLDivElement>(null);
return <App value="hello" ref={ref} />;
React.ForwardRefRenderFunction
Функции, определенные как этот тип, могут быть помещены вReact.forwardRefфункция как параметр
// 定义
const forwardRender: React.ForwardRefRenderFunction<
HTMLDivElement,
AppProps
> = ({ value }, ref) => {
return <div ref={ref} />;
};
const App = React.forwardRef(forwardRender);
// 使用
const ref = useRef<HTMLDivElement>(null);
return <App value="hello" ref={ref} />;
React.createContext
Обобщения имеют функцию автоматического вывода, поэтомуuseContextБольше не нужно писать тип
interface ContextType {
getPrefixCls: (value: string) => string;
}
const context = React.createContext<ContextType>({
getPrefixCls: (value) => `prefix-${value}`,
});
const App = () => {
const { getPrefixCls } = useContext(context);
getPrefixCls("App"); // prefix-App
return null;
};
React.cloneElement
если используетсяReact.FCопределенный компонент, егоchildrenВведите значение по умолчаниюReact.ReactNode, который необходимо явно преобразовать вReact.ReactElement
const App: React.FC = ({ children }) => {
return React.cloneElement(children as React.ReactElement, { value: "hello" });
};
// 也可以覆写定义
const App: React.FC<{ children: React.ReactElement }> = ({ children }) => {
return React.cloneElement(children, { value: "hello" });
};
React.ComponentType
пройти черезReact.ComponentType<P>Определенный компонент может передать имя переменной компоненту и вызвать его внутри компонента.Компоненты более высокого порядка обычно используют
interface AppProps {
value: string;
}
const App: React.FC<AppProps> = (props) => {
return null;
};
// React.ComponentType定义组件
function HOC<T>(Component: React.ComponentType<T>) {
return function (props: T) {
return <Component {...props} />;
};
}
const WrappedComponent = HOC(App);
// 调用
<WrappedComponent value="hello" />
Компоненты общих параметров
Компоненты общего параметра:typescriptНовое в версии 2.9, первый раз увидел вant-deisgnвнутри
Очень простой примерSelectкомпоненты
<Select<number>>
<Select.Option value={1}>1</Select.Option>
<Select.Option value={2}>2</Select.Option>
</Select>
определение компонента класса
// 定义泛型参数的组件
class GenericComponent<P> extends React.Component<P> {
internalProp: P;
constructor(props: P) {
super(props);
this.internalProp = props;
}
render() {
return null;
}
}
type Props = { a: number; b: string };
<GenericComponent<Props> a={10} b="hi" />; // OK
<GenericComponent<Props> a={10} b={20} />; // Error
Определение функциональных компонентов
function GenericComponent<P>(props: P) {
const internalProp = useRef(props)
return null;
}
Компоненты стрелочных функций также могут использовать дженерики при определенных условиях.
// 这样会解析错误
const GenericComponent = <P>(props: P) =>{
const internalProp = useRef(props);
return null;
}
// 泛型必须使用extends关键字才能解析
const GenericComponent = <P extends any>(props: P) =>{
const internalProp = useRef(props);
return null;
}
Функциональные компоненты могут быть написаны гораздо более лаконично...
обработка событий
также разнообразный
const App = () => {
// React.MouseEventHandler
const onClick: React.MouseEventHandler<HTMLInputElement> = (e) => {
console.log(e.currentTarget.value);
};
// React.ChangeEventHandler
const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
console.log(e.currentTarget.value);
};
// React.FocusEventHandler
const onFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {
console.log(e.currentTarget.value);
};
return <input onClick={onClick} onChange={onChange} onFocus={onFocus} />;
};
Если есть событие, для которого непонятно, как определить тип, вы можете щелкнуть имя события на компоненте, чтобы увидеть определение.
Следует отметить, что толькоe.currentTargetБудет соответствующий тип элемента,e.targetнет, его типEventTarget
Суммировать
Ничего другого не могу придумать, добавлю еще, когда вспомню
tsПоставляется с некоторыми универсальными инструментами, такими какOmit,Pick,Это все еще полезно при разработке, вы можете увидеть мои предыдущиеСуммировать
Напоследок желаю всем крепкого здоровья и легкой работы!
Жаль, что в tsx нет даже подсветки кода, можно только сказать, что она до сих порprismjsочень хорошо,highlightjsне очень хорошо