web/react

react with typescript(Props, PropsWithChildren, Function Components, Hooks)

방방곡곡 2022. 11. 28. 16:06

Basic prop types

type AppProps = {
  message: string;
  count: number;
  disabled: boolean;
  /** array of a type! */
  names: string[];
  /** string literals to specify exact string values, with a union type to join them together */
  status: "waiting" | "success";
  /** an object with known properties (but could have more at runtime) */
  obj: {
    id: string;
    title: string;
  };
  /** array of objects! (common) */
  objArr: {
    id: string;
    title: string;
  }[];
  /** any non-primitive value - can't access any properties (NOT COMMON but useful as placeholder) */
  obj2: object;
  /** an interface with no required properties - (NOT COMMON, except for things like `React.Component<{}, State>`) */
  obj3: {};
  /** a dict object with any number of properties of the same type */
  dict1: {
    [key: string]: MyTypeHere;
  };
  dict2: Record<string, MyTypeHere>; // equivalent to dict1
  /** function that doesn't take or return anything (VERY COMMON) */
  onClick: () => void;
  /** function with named prop (VERY COMMON) */
  onChange: (id: number) => void;
  /** function type syntax that takes an event (VERY COMMON) */
  onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
  /** alternative function type syntax that takes an event (VERY COMMON) */
  onClick(event: React.MouseEvent<HTMLButtonElement>): void;
  /** any function as long as you don't invoke it (not recommended) */
  onSomething: Function;
  /** an optional prop (VERY COMMON!) */
  optional?: OptionalType;
  /** when passing down the state setter function returned by `useState` to a child component. `number` is an example, swap out with whatever the type of your state */
  setState: React.Dispatch<React.SetStateAction<number>>;
};

 

Props With Children

ReactNode

Basic Prop Types 에서 children의 타입을 ReactNode로 할당

import {ReactNode} from 'react';

type ComponentsProps = {
    foo: string;
    children: ReactNode;
}
// children이 옵션이면 chidren?: ReactNode

 

PropsWithChildren

// react/index.d.ts
type PropsWithChildren<P> = P & { children?: ReactNode };

// use
type ComponentProps = PropsWithChildren<{foo: string}>;

 

function

FC(FunctionComponent)

PropsWithChildren이 아래에서 동작

type ComponentProps = {
  foo: string
}
const Component: React.FunctionComponent<ComponentProps> = ({foo}) =>
  <span>{foo}</span>

// same
const Component: React.FC<ComponentProps> = ({foo}) =>
  <span>{foo}</span>

 

etc

// Declaring type of props - see "Typing Component Props" for more examples
type AppProps = {
  message: string;
}; /* use `interface` if exporting so that consumers can extend */

// Easiest way to declare a Function Component; return type is inferred.
const App = ({ message }: AppProps) => <div>{message}</div>;

// you can choose annotate the return type so an error is raised if you accidentally return some other type
const App = ({ message }: AppProps): JSX.Element => <div>{message}</div>;

// you can also inline the type declaration; eliminates naming the prop types, but looks repetitive
const App = ({ message }: { message: string }) => <div>{message}</div>;

웬만하면 추론이 나을듯?

hooks

useState

  1. 간단한 값에는 타입 추론(inference)가 잘 작동한다.
const [state, setState] = useState(false);
// `state` is inferred to be a boolean
// `setState` only takes booleans


2. 널로 초기화 되는 경우의 타입 Explicitly declare the type, and use a union type ```tsx const [user, setUser] = useState(null);

// later...
setUser(newUser);

<br>
3. 초기값 이후에 항상 값이 있다면: type assertions
```tsx
const [user, setUser] = useState<User>({} as User);
// later...
setUser(newUser);

This temporarily "lies" to the TypeScript compiler that {} is of type User. You should follow up by setting the user state — if you don't, the rest of your code may rely on the fact that user is of type User and that may lead to runtime errors
흠흠

useEffect(useLayoutEffect)

  • useEffect: DOM 페인트 이후에 호출
  • useLayoutEffect: DOM 그려지기 이전에 호출

반환값이 없을 땐 타입이 필요없다.
있을 땐 function or undefined



참조

https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/hooks/ https://www.newline.co/@bespoyasov/how-to-define-props-with-children-in-react-typescript-app--56bd18be