使用 TypeScript 渲染带有 State 和 Props 的 React 组件
介绍
使用 TypeScript 编写包含 props 和 state 的组件是构建应用所需的核心任务之一。虽然函数式组件和类组件都可以包含 props 和 state,但本指南将介绍如何创建和渲染类组件。
这在将 React 类组件迁移到 TypeScript 或从头开始编写时非常有用。
用例
假设有一个网页在屏幕上显示著名名言,还有一个按钮,点击后会呈现一条新名言。此功能要求组件同时具有 props 和 state。一组名言将以 props 和 state 的形式传递。该组件跟踪屏幕上显示的当前名言。
设置 React TypeScript 应用程序
打开您的终端并运行这些命令以在您的机器上运行示例 TypeScript 应用程序。
npx create-react-app my-app --template typescript
cd my-app
yarn start
要在开发模式下运行应用,请在浏览器中打开 https://localhost:3000。您应该会看到示例 TypeScript 应用正在运行。
添加 QuoteApp 组件
删除src目录中的App.tsx文件。现在创建一个新组件src/QuoteApp.tsx并添加以下代码。
import React from 'react';
import './App.css';
type QuoteProps = {
quotes: string[]
}
type QuoteState = {
currentIndex: number,
}
export default class QuoteApp extends React.Component<QuoteProps, QuoteState> {
render() {
return <div className="App">
<header className="App-header">
<h3>Render Component with State and Props using TypeScript</h3>
</header>
</div>
}
}
在上面的代码中,<QuoteApp>是一个类组件,而在 TypeScript 中,React.Component被定义为一个泛型,具有两个可选的类型参数。第一个用于 prop 类型,第二个用于 state 类型。
QuoteProps是为<QuoteApp>组件中允许的 props 定义的类型。 <QuoteApp>组件的调用者应在 props 中传递一个字符串数组,其中包含要显示的引文。QuoteState是为<QuoteApp>组件的状态定义的类型。它包含类型为number的currentIndex。这是从集合中呈现的引文的当前索引。在render()函数中,将返回一个<div>,该 <div> 在网页上显示标题,标题文本呈现在<h3>元素内。
使用 State 和 Props 渲染组件
现在是时候在网页上显示引言和一个按钮,以便用户可以点击它。下面的代码可以完成这项工作。<QuoteApp>组件具有QuoteState类型的状态,其currentIndex的初始值为零。当使用 props quotes(字符串数组)调用该组件时,quoteToDisplay变量从该数组中获取currentIndex处的元素并呈现它。<div>元素包含内联样式以使其具有适当的对齐方式,并且引言显示在 HTML 标题<h4>内。
添加一个带有标签“NEXT QUOTE”的<button>。当用户点击此按钮时,将调用getNextQuote()函数。它返回void并使用currentIndex的新值更新状态。它还调用getIndex()函数,该函数的作用是返回报价数组的最后一个索引与零之间的随机数。
简而言之,当用户点击 NEXT QUOTE 按钮时,getNextQuote()函数会通过调用getIndex()函数获取索引的新值。一旦currentIndex值更新,就会呈现该索引处的报价。
import React from 'react';
import './App.css';
type QuoteProps = {
quotes: string[]
}
type QuoteState = {
currentIndex: number,
}
export default class QuoteApp extends React.Component<QuoteProps, QuoteState> {
state: QuoteState = {
currentIndex: 0,
};
getIndex = (): number => {
const min: number = 0;
const max: number = this.props.quotes.length - 1;
return Math.floor(Math.random() * (max - min) + min);
};
getNextQuote = (): void => this.setState(state => ({currentIndex: this.getIndex()}));
render() {
const quoteToDisplay = this.props.quotes[this.state.currentIndex];
return <div className="App">
<header className="App-header">
<h3>Render Component with State and Props using TypeScript</h3>
</header>
<div style={{height: "5vh", padding: "1em", margin: "7em"}}>
<h4>{quoteToDisplay}</h4>
</div>
<button onClick={this.getNextQuote}>NEXT QUOTE</button>
</div>
}
}
调用 QuoteApp 组件
现在<QuoteApp>组件已准备好被调用。它所需要的只是一个引号数组。转到src/index.tsx文件并用此代码替换该文件中的代码。
randomQuotes是包含引号的字符串数组。<QuoteApp>组件使用 prop quotes及其值randomQuotes进行调用。
转到浏览器并打开 https://localhost:3000。您应该在屏幕上呈现一条引言,它是引言数组中索引为零的引言。每次单击按钮时,它都会显示一条新引言。
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import QuoteApp from './QuoteApp';
import * as serviceWorker from './serviceWorker';
const randomQuotes: string[] = [
"Before you judge a man, walk a mile in his shoes. After that who cares?... He’s a mile away and you’ve got his shoes!",
"Better to remain silent and be thought a fool than to speak out and remove all doubt.",
"The best thing about the future is that it comes one day at a time.",
"The only mystery in life is why the kamikaze pilots wore helmets.",
"Light travels faster than sound. This is why some people appear bright until you hear them speak.",
"The difference between stupidity and genius is that genius has its limits"
]
ReactDOM.render(
<React.StrictMode>
<QuoteApp quotes={randomQuotes}/>
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
GitHub 上的代码
您可以在GitHub上访问此示例的完整代码
结论
您学习了如何使用 TypeScript 渲染具有状态和属性的类组件。在此代码示例中,我们使用类型别名来声明属性和状态类型QuoteProps和QuoteState。这是因为QuoteProps和QuoteState都是简单的对象类型文字,并且严格限制了这些对象的结构。但如果需要在代码中实现或扩展该接口,您也可以使用QuoteProps的TypeScript接口。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~