React and Typescript are used in conjunction with Typescript. Use vscode prompts to write things down and add them later.
Define the component props type
import React from 'react';
// type
type AppProps = {
name: string;
children: React.ReactNode;
status: 'success' | 'error';
};
// interface
interface AppProps {
name: string;
children: React.ReactNode;
status: 'success' | 'error';
}
const App = ({ name, children, status }: AppProps) = > (
<div>
<span>{name}</span>
<span>{status}</span>
{children}
</div>
);
export default App;
Copy the code
- In the React component, it is recommended to use type to define Props and State, which is more restrictive than interface
- Typescript manual Type vs. Interface
JSX. Element and the React. ReactNode?
type AppProps = {
children: JSX.Element | React.ReactNode;
};
const App = ({ children }: AppProps) = > {
return <>children</>;
};
const Index = () = > {
return (
// When children is jsx. Element, children can only be a JSX Element tag and cannot be a string, for example:
text
<App>
<span>asda</span>
</App>
// When children is react. ReactNode, children can be any element
<App>A description</App>
);
};
export default Index;
// react. ReactNode is a collection of all possible return types for a component
Copy the code
Define the Function Components
import React from 'react';
type AppProps = {
name: string;
};
// react. FC defines the props type, which has the children property by default
const App: React.FC<AppProps> = ({ name, children }) = > <div>{name}</div>;
/ / don't need to children in parameter type way or React. VoidFunctionComponent < AppProps >
const App = ({ name }: AppProps) = > <div>{name}</div>;
export default App;
Copy the code
UseState and useRef
const App = () = > {
// Undefined by default
const [name, setName] = useState<string | undefined> ();// ref
const divRef = useRef<HTMLDivElement>(null);
return <div ref={divRef}>{name}</div>;
};
Copy the code
useImperativeHandle
// the parent component calls the parent component's methods. The first type of the forwardRef is the property mounted on ref, and the second type is props
type Props = { name: string };
type Ref = {
sayHello: () = > void;
};
const Child = forwardRef<Ref, Props>(({ name }, ref) = > {
useImperativeHandle(ref, () = > ({
sayHello: () = > console.log('hello'),}));return <div>{name}</div>;
});
const Parent = () = > {
const childRef = useRef<Ref>(null);
return (
<div>
<Child ref={childRef} name="child"></Child>
</div>
);
};
Copy the code
useContext
import React from 'react';
interface AppContextInterface {
name: string;
}
// null! Indicates that the value is not null and must exist
const AppCtx = React.createContext<AppContextInterface>(null!). ;const sampleAppContext: AppContextInterface = {
name: 'Typescript React App'};export const App = () = > (
<AppCtx.Provider value={sampleAppContext}>.</AppCtx.Provider>
);
export const PostInfo = () = > {
const appContext = React.useContext(AppCtx);
return <div>Name: {appContext.name}</div>;
};
Copy the code
createPortal
import React, { useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
const modalRoot = document.body;
const Modal: React.FC<{}> = ({ children }) = > {
const el = useRef(document.createElement('div'));
useEffect(() = > {
const current = el.current;
modalRoot.appendChild(current);
return () = > voidmodalRoot.removeChild(current); } []);return createPortal(children, el.current);
};
export default Modal;
// createPortal can render components to specified elements, such as ANTD's Modal
Copy the code
Ts Some usage tips
/ /! Indicates that type inference excludes undefined and NULL
document.getElementById('root')! .parentNode;// Type combination
type AnimalType = {
name: string;
};
type DogType = {
age: number;
};
const Dog = ({ name, age }: AnimalType & DogType) = > (
<div>
{name}
{age}
</div>
);
// Through interface inheritance
interface AnimalInterface {
name: string;
}
interface DogInterface extends AnimalInterface {
age: string;
}
const Dog = ({ name, age }: DogInterface) = > (
<div>
{name}
{age}
</div>
);
Copy the code
// Define the function type
type FunctionType = (x: number, y: number) = > number;
type FunctionType1 = (x: number, y: number) = > Promise<number>;
Copy the code
// Function overload
// Overload: the method name is the same, the parameter type is different, the return value type can also be different
function renderTable(data: { name: string; age: number }) :number;
function renderTable(data: string) :string;
function renderTable(data) :any {
// bala bala bala....
}
renderTable({ name: '1'.age: 1 });
renderTable('hello');
Copy the code
// typeof gets the typeof a variable without redeclaring it
const App = () = > {
const [state, setState] = React.useState({
name: 'Ming'.age: 2});const method = (obj: Partial<typeof state>) = > {
setState(obj);
};
}
// Partial
-> { name? :string; age: number; }
Copy the code
// Omit an attribute from a type
type User = {
id: string;
name: string;
email: string;
};
type UserWithoutEmail = Omit<User, 'email'>;
Omit<User, 'email'> is equivalent totype UserWithoutEmail = {
id: string;
name: string;
};
Copy the code
Imitate write a useSafeState hooks
// The main idea is to use a variable to mark whether or not the component is uninstalled. If uninstalled, do not setState, so that there is no memory leak and other unexpected conditions
import { useState, useEffect, useRef, Dispatch, SetStateAction } from 'react';
function useSafeState<S> (initialState: S | (() => S)) :S.Dispatch<SetStateAction<S> >];
function useSafeState<S = undefined> () :S | undefined.Dispatch<SetStateAction<S | undefined> >,);
function useSafeState<T> (initialValue? : T) {
const [state, setState] = useState(initialValue);
const isUnMounted = useRef(false);
useEffect(() = > {
return () = > {
isUnMounted.current = true; }; } []);const setSafeState = (value: T) = > {
if (!isUnMounted.current) {
setState(value);
}
};
return [state, setSafeState] as const;
}
export default useSafeState;
Copy the code
- See react-typescript-Cheatsheet