在前端开发中,React 是一个非常流行的框架,而 TypeScript 则是一种强类型的 JavaScript 语言。在实际开发中,我们常常需要使用 TypeScript 来编写 React 组件,这就需要我们学习 TypeScript 中 JSX 语法和 React 组件的创建及相互转换方法。
一、JSX 语法
JSX 是一种类似于 XML 的语法,用于描述 React 组件的 UI。在 TypeScript 中,我们可以使用 JSX 语法来编写 React 组件的模板。
1.1 JSX 的基本语法
在 JSX 中,我们可以使用类似于 HTML 的语法来描述 UI,如下所示:
const element = <h1>Hello, world!</h1>;
在上面的代码中,<h1>Hello, world!</h1> 就是一个 JSX 元素。在编译时,TypeScript 会将 JSX 元素转换为 JavaScript 代码,如下所示:
const element = React.createElement("h1", null, "Hello, world!");1.2 JSX 中的表达式
在 JSX 中,我们可以使用花括号 {} 来插入 JavaScript 表达式,如下所示:
const name = "John";
const element = <h1>Hello, {name}!</h1>;在上面的代码中,{name} 就是一个 JavaScript 表达式,它会被解析为字符串,最终输出为 Hello, John!。
1.3 JSX 中的属性
在 JSX 中,我们可以使用属性来配置组件的行为和样式,如下所示:
const element = <img src="logo.png" alt="Logo" />;
在上面的代码中,src 和 alt 就是组件的属性。在编译时,TypeScript 会将 JSX 属性转换为 JavaScript 对象,如下所示:
const element = React.createElement("img", { src: "logo.png", alt: "Logo" });二、React 组件的创建
在 TypeScript 中,我们可以使用类和函数两种方式来创建 React 组件。下面分别介绍这两种方式的创建方法。
2.1 类组件的创建
类组件是一种通过继承 React.Component 类来创建的组件。下面是一个简单的类组件的示例:
// www.javascriptcn.com code example
import React from "react";
interface Props {
name: string;
}
interface State {
count: number;
}
class MyComponent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { count: 0 };
}
render() {
return (
<div>
<h1>Hello, {this.props.name}!</h1>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState((state) => ({ count: state.count + 1 }))}>Click me</button>
</div>
);
}
}在上面的代码中,MyComponent 组件继承了 React.Component 类,并实现了 Props 和 State 两个接口。Props 接口定义了组件的属性,State 接口定义了组件的状态。在构造函数中,我们初始化了组件的状态。在 render 方法中,我们使用 JSX 语法来描述组件的 UI。
2.2 函数组件的创建
函数组件是一种通过函数来创建的组件。下面是一个简单的函数组件的示例:
// www.javascriptcn.com code example
import React from "react";
interface Props {
name: string;
}
const MyComponent: React.FC<Props> = ({ name }) => {
const [count, setCount] = React.useState(0);
return (
<div>
<h1>Hello, {name}!</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
};在上面的代码中,MyComponent 组件是一个函数,接受一个 Props 参数,并返回一个 JSX 元素。在函数内部,我们使用 React.useState Hook 来定义组件的状态。
三、组件的相互转换
在实际开发中,我们常常需要将类组件转换为函数组件,或者将函数组件转换为类组件。下面分别介绍这两种转换方法。
3.1 类组件转函数组件
类组件转函数组件的方法很简单,只需要将类组件的 render 方法中的 JSX 语法部分提取出来,放到一个函数中即可。下面是一个示例:
// www.javascriptcn.com code example
import React from "react";
interface Props {
name: string;
}
interface State {
count: number;
}
class MyComponent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { count: 0 };
}
render() {
return (
<div>
<h1>Hello, {this.props.name}!</h1>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState((state) => ({ count: state.count + 1 }))}>Click me</button>
</div>
);
}
}
const MyFunctionalComponent: React.FC<Props> = ({ name }) => {
const [count, setCount] = React.useState(0);
return (
<div>
<h1>Hello, {name}!</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
};
// 类组件转函数组件
const MyComponent2: React.FC<Props> = (props) => <MyFunctionalComponent {...props} />;在上面的代码中,我们将 MyComponent 类组件转换为 MyFunctionalComponent 函数组件,并使用 <MyFunctionalComponent {...props} /> 的方式来传递属性。
3.2 函数组件转类组件
函数组件转类组件的方法稍微复杂一些,我们需要使用 React.Component 类来创建一个类组件,并实现 render 方法。下面是一个示例:
// www.javascriptcn.com code example
import React from "react";
interface Props {
name: string;
}
const MyFunctionalComponent: React.FC<Props> = ({ name }) => {
const [count, setCount] = React.useState(0);
return (
<div>
<h1>Hello, {name}!</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
};
class MyComponent extends React.Component<Props> {
render() {
const { name } = this.props;
return <MyFunctionalComponent name={name} />;
}
}
// 函数组件转类组件
const MyFunctionalComponent2: React.FC<Props> = (props) => <MyComponent {...props} />;在上面的代码中,我们将 MyFunctionalComponent 函数组件转换为 MyComponent 类组件,并使用 <MyFunctionalComponent name={name} /> 的方式来渲染 JSX 元素。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/67d0e199a941bf71341d93a2