TypeScript로 마이그레이션 하기(react)

js·2021년 8월 31일
0

타입스크립트

목록 보기
1/4

State

extends Component <{}, 인터페이스명>

import React, { Component } from "react";

interface IState {
  counter: number;
}

class App extends Component<{}, IState> {
  state = {
    counter: 0
  };
  render() {
    const { counter } = this.state;
    return (
      <div>
        {counter} <button onClick={this.add}>Add</button>
      </div>
    );
  }
  add = () => {
    this.setState(prev => {
      return {
        counter: prev.counter + 1
      };
    });
  };
}

export default App;

Props

함수 컴포넌트는 React.FunctionComponent <인터페이스명>

ts 적용 전

const Container = styled.span``;

const Number = ({ count }) => (
  <Container>{count}</Container>
);

export default Number;

ts 적용 후

const Container = styled.span``;

interface IProps {
  count: number;
}

const Number: React.FunctionComponent<IProps> = ({ count }) => (
  <Container>{count}</Container>
);

export default Number;

Event

1) return 값이 없으면 void

2) 폼에서 발생하는 event의 type은 React.FormEvent

3) input에서 발생하는 event의 type은 React.SyntheticEvent<'HTMLInputElement'>

ts 적용 후, Input.tsx

import React from "react";

interface IInputProps {
  value: string;
  onChange: (event: React.SyntheticEvent<HTMLInputElement>) => void;
}

export const Input: React.FunctionComponent<IInputProps> = ({
  value,
  onChange
}) => (
  <input type="text" placeholder="Name" value={value} onChange={onChange} />
);

interface IFormProps {
  onFormSubmit: (event: React.FormEvent) => void;
}

export const Form: React.FunctionComponent<IFormProps> = ({
  children,
  onFormSubmit
}) => <form onSubmit={onFormSubmit}> {children}</form>;

App.tsx

import React, { Component } from "react";
import Number from "./Number";
import { Form, Input } from "./Input";

interface IState {
  counter: number;
  name: string;
}

class App extends Component<{}, IState> {
  state = {
    counter: 0,
    name: ""
  };
  render() {
    const { counter, name } = this.state;
    return (
      <div>
        <Form onFormSubmit={this.onFormSubmit}>
          <Input value={name} onChange={this.onChange} />
        </Form>
        <Number count={counter} /> <button onClick={this.add}>Add</button>
      </div>
    );
  }

  onChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
    console.log(event.target);
  };

  onFormSubmit = (event: React.FormEvent) => {
    event.preventDefault();
  };

  add = () => {
    this.setState(prev => {
      return {
        counter: prev.counter + 1
      };
    });
  };
}

export default App;

Styled-Components

1) 따로 인터페이스를 선언해도 되지만 인터페이스가 많아질 경우를 대비해 한줄로 선언한다

ex) styled.span<{ props명: 타입}>

2) theme는 styled.d.ts를 생성해준다

src/theme.ts

export default {
  blueColor: "red"
};

src/styled.d.ts

import "styled-components";

declare module "styled-components" {
  export interface DefaultTheme {
    blueColor: string;
  }
}

src/index.tsx

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { ThemeProvider } from "styled-components";
import theme from "./theme";

ReactDOM.render(
  <ThemeProvider theme={theme}>
    <App />
  </ThemeProvider>,
  document.getElementById("root")
);

src/Number.tsx

import styled from "styled-components";

const Container = styled.span<{ isBlue: boolean }>`
  color: ${props => (props.isBlue ? "blue" : "black")};
  color: ${props => (props.isBlue ? props.theme.blueColor : "black")};
`;

0개의 댓글