在React项目中使用TypeScript(持续更新)

安装脚手架

npm install -g create-react-app

创建项目

create-react-app proName --typescript

小试牛刀

可以把ts的代码注释查看编译器报错提示

Class组件

src文件夹下创建pages/home/Home.tsx

import React, { Component } from "react";
// 规定props有name属性,且类型是string类型(如果注释组件内使用props.name将报错)
interface IProps {
  name: string;
}
// 规定state有color属性且值只为red或者blue
interface IState {
  color: "red" | "blue";
}
export default class Home extends Component<IProps, IState> {
  constructor(props: IProps) {
    super(props);
    this.state = {
      color: "red"
    };
  }
  render() {
    return (
      <div>
        <span style={{ color: this.state.color }}>
          {this.props.name}中国加油!
        </span>
        <br />
        <button onClick={this.changeColor}>change color</button>
      </div>
    );
  }

  changeColor = () => {
    let color = this.state.color;
    if (color === "red") {
      this.setState({
        color: "blue"
      });
    } else {
      this.setState({
        color: "red"
      });
    }
  };
}

App.tsx引入

import React} from "react";
import "./App.css";
// import 
import Home from "./pages/home/Home";
function App() {
  return (
    <div className="App">
      {/*传值给Home组件,如果Home内没有 name: string; 代码将报错*/}
      <Home name="Change say:" />
    </div>
  );
}
export default App;
函数式组件

src文件夹下创建pages/counter/Counter.tsx

/*简单的计数器代码*/
import React from "react";

// props包含count,increment,decrement,且类型确定
interface IProps {
  count: number;
  increment: () => void;
  decrement: () => void;
}

const Counter = ({ count, increment, decrement }: IProps) => {
  return (
    <div>
      <h1>{count}</h1>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
    </div>
  );
};

export default Counter;

App.tsx引入

import React, { useState, useCallback } from "react";
import "./App.css";
import Counter from "./pages/counter/Counter";
function App() {
  const [count, setCount] = useState(1);
  const increment = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  const decrement = useCallback(() => {
    setCount(count - 1);
  }, [count]);

  return (
    <div className="App">
      {/*必须按类型传count、increment、decrement过去,不然代码报错*/}
      <Counter count={count} increment={increment} decrement={decrement} />
    </div>
  );
}

export default App;

高阶组件

src文件夹下创建components/Hoc.tsx

/*添加版权的高阶组件*/
import React, { Component } from "react";

export class App extends Component {
  render() {
    return (
      <div>
        <h1>react</h1>
        <p>React.js 是一个构建用户界面的库</p>
      </div>
    );
  }
}

/*需要规定Com的类型,可以用any,但是当const CopyrightApp = withCopyright(123);时编辑器不会检查出错误,但是代码运行会报错,因为withCopyright(需要是一个组件)*/
// 规定Com是react组件类型
const withCopyright = (Com: React.ComponentType) => {
  return class extends Component {
    render() {
      return (
        <>
          <Com />
          <div>@copyright; 版权所有 xxx</div>
        </>
      );
    }
  };
};

const CopyrightApp = withCopyright(App);

export default CopyrightApp;

App.tsx引入

import React from "react";
import "./App.css";
import Hoc from "./pages/components/Hoc";
function App() {
  return (
    <div className="App">
      <Hoc />
    </div>
  );
}

export default App;

Event

src文件夹下创建components/Botton.tsx

import React, { ReactNode } from "react";

// 与interface等价
type IProps = {
  // react节点类型
  children: ReactNode;
  // react鼠标事件类类型
  click(e: React.MouseEvent): void;
};
const Button = (props: IProps) => {
  return (
    <div>
      <button onClick={props.click}>{props.children}</button>
    </div>
  );
};

export default Button;

App.tsx引入

import React, { useState, useCallback } from "react";
import "./App.css";
import Button from "./pages/components/Button";
function App() {
    // 此处如果e不给类型将推断为any,当你打 e.时编译器不会有提示,但是当e给了 React.MouseEvent类型时,e. 编译器将有提示(提示有什么属性)
  const click = useCallback((e: React.MouseEvent) => {
    console.log(e);
  }, []);
  return (
    <div className="App">
      <Button click={click}>button test</Button>
    </div>
  );
}

export default App;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章