导航
class Welcome extends React.Component {
render() {
return <div>Welcome</div>
}
}
function Welcome() {
return <div>Welcome</div>
}
// 类组件
class Welcome extends React.Component {
constructor() {
this.state = {
name: 'Lance'
};
}
render() {
return <div>Welcome</div>;
}
}
// 函数式组件
function Welcome() {
const [count, setCount] = useState(0);
return <div>Welcome</div>;
}
function Welcome(props) {
return <div>{ props.name }</div>;
}
const element = <Welcome name="Lance" />
项目初始化就是我们平常所说的工程化
在初始化时,我们需要考虑这个项目:
如果是企业级项目,除了技术层内容考虑以外,还需要重点关注:
通常使用脚手架,不用关心初始化的细节
pnpm create vite react-vite-cli-demo --template react-ts # react ts 的模板创建方式
pnpm i
pnpm run dev
npx create-react-app react-cra-demo --template typescript
Vite
创建项目目录并初始化
mkdir my-react-app
cd my-react-app
npm init -y
安装 Vite 和相关依赖
pnpm i [email protected] @vitejs/[email protected] -D
pnpm i [email protected] [email protected]
{
"name": "my-react-app",
"version": "1.0.0",
"description": "",
"type": "module",
"script": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"keywords": [],
"dependencies": {
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"vite": "5.3.1",
"@vitejs/plugin-react": "1.0.0"
}
}
创建 vite 配置
import { defineConfig } from "vite" ;
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
}
});
创建根组件和入口文件
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
return <div>123</div>
}
export default App;
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
创建静态资源
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
jsx 全称是:javaScript and xml,在 JavaScript 代码中编写 html 代码的一种规范。
规范是为编译器设计的。
const element = <h1>Hello, world!</h1>;
jsx 通过编译器进行转换,babel(@babel/preset-react、plugin-transform-react-jsx)
通过 jsx 转换后,代码就变成了 js 引擎可以执行的代码了。
import { jsx as _jsx } from "react/jsx-runtime";
const element = /*#__PURE__*/_jsx("h1", {
children: "Hello, world!"
});

还没完,再在 react 运行时,通过 react 定义的 jsx 创建出 ReactElement
https://github.com/facebook/react/blob/a2329c10ffc153303ad5a65b99d91d8500ceabdd/packages/react/src/jsx/ReactJSX.js#L19
https://github.com/facebook/react/blob/a2329c10ffc153303ad5a65b99d91d8500ceabdd/packages/react/src/jsx/ReactJSXElement.js#L330
return ReactElement(type, key, props, getOwner(), undefined, undefined);
类组件
import React from "react";
export interface BasicProps {
name: string;
}
export interface BasicState {
count: number;
}
export class Basic extends React.Component<BasicProps, BasicState> {
constructor(props: BasicProps) {
super(props);
this.state = {
count: 0,
}
}
render() {
return (
<div
onClick={() => {
this.setState({
count: this.state.count + 1;
});
}}
>Hello, Class Component Basic! {this.state.count}</div>
);
}
}
函数组件
import React, { useState } from "react";
export interface BasicProps {
name: string;
}
export const Basic: React.FC<BasicProps> = () => {
const [count, setCount] = useState(0);
return (
<div onClick={() => setCount(count + 1)}>
Hello, Functional Component Basic! {count}
</div>
);
}
import React from "react";
export interface PropsProps {
name: string;
info: {
age: number;
address: string;
};
}
export const Props: React.FC<PropsProps> = ({ name }) => {
return <div>Hello, Functional Component Basic! {name}</div>;
}
import { Props } from "./fcc/Props";
function App() {
return (
<div>
<Props name="Lance" info={{
age: 18,
address: 'Shanghai'
}} />
</div>
);
}
import React, { useState } from "react";
export interface StateProps {}
export const State: React.FC<StateProps> = () => {
const [count, setCount] = useState(0); // 或者初始化函数 useState(() => 0); // 通过函数调用初始化值
return (
<div onClick={() => setCount(count + 1)}>
Hello, Functional Component Basic! {count}
</div>
);
}
import React, { useState } from "react";
export interface ConditionProps {}
export const Condition: React.FC<ConditionProps> = () => {
const [count, setCount] = useState(0);
const contentText = count % 2 === 0 ? '偶数' : '奇数';
return (
<div onClick={() => setCount(count + 1)}>
Hello, Functional Component Basic! {count} {contentText}
</div>
);
}
onClick vs onclick)import React, { useState } from "react";
export interface EventProps {}
export const Event: React.FC<EventProps> = () => {
const [count, setCount] = useState(0);
const contentText = count % 2 === 0 ? '偶数' : '奇数';
const handleClick = (ev: React.MouseEvent) => {
console.log("🚀 ~ handleClick ~ ev:", ev.target, ev.currentTarget);
setCount(count + 1)
};
return (
<div onClick={handleClick}>
Hello, Functional Component Basic! {count} {contentText}
<div
draggable
onDragStart={ (ev) => console.log(ev) }
onDragEnd={ (ev) => console.log(ev) }
>拖拽</div>
<div
contentEditable
onCopy={console.log}
onPaste={console.log}
>我是可编辑的</div>
</div>
);
}