安裝腳手架
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;