使用React的语言翻译器
语言翻译器是一款使用ReactJS的网页应用软件工具,可帮助将文本从一种语言翻译成另一种语言。该应用允许用户提供输入文本,并从语言列表中选择输入和输出语言格式,使用微软翻译API进行翻译。用户还可以反转源语言和目标语言,并清除输入文本。该组件提供了一个用户友好的界面,具有动态更新和错误处理功能。该应用使用ReactJS实现,具有简单和响应式的用户界面。
最终输出预览:
先决条件和技术:
- ReactJS
- CSS
- React中的功能组件
- Rapid API
方法/功能:
该项目基本上实现了功能组件并管理状态。该应用程序使用Microsoft Translator API进行语言翻译,通过输入文本和语言首选项进行POST请求。在接收到响应后,翻译后的文本会更新到组件的状态中,并且在API调用期间会显示加载指示器。组件的界面允许用户选择语言、输入文本、翻译和反转语言选择。如果API调用被拒绝,则在翻译过程中显示错误消息。
创建应用程序的步骤:
步骤 1: 使用命令设置React项目
npx create-react-app <<name of project>>
步骤2: 导航到项目文件夹,使用以下命令:
cd <<Name_of_project>>
步骤3: 创建一个名为“components”的文件夹,并在其中添加三个新文件,分别命名为Translator.js、language.json和Translator.css。
项目结构:
package.json 中的已更新依赖项将看起来像这样:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
示例: 将下面的代码分别写入相应的文件中
- App.js: 此文件导入Translator组件并将其导出。
- Translator.js: 此文件包含一个逻辑,允许用户插入输入文本并选择输入和输出语言格式,并使用API获取翻译文本。
- language.json: 此文件包含语言及其对应名称的列表。
- Translator.css: 此文件包含Translator元素的设计。
// App.js
import './App.css';
import Translator from './components/Translator';
function App() {
return (
<div className="App">
<Translator />
</div>
);
}
export default App;
// language.json
{
"af": { "name": "Afrikaans" },
"ak": { "name": "Akan" },
"sq": { "name": "Albanian" },
"am": { "name": "Amharic" },
"ar": { "name": "Arabic" },
"hy": { "name": "Armenian" },
"as": { "name": "Assamese" },
"ay": { "name": "Aymara" },
"az": { "name": "Azerbaijani" },
"bm": { "name": "Bambara" },
"eu": { "name": "Basque" },
"be": { "name": "Belarusian" },
"bn": { "name": "Bengali" },
"bs": { "name": "Bosnian" },
"bg": { "name": "Bulgarian" },
"my": { "name": "Burmese" },
"ca": { "name": "Catalan; Valencian" },
"ny": { "name": "Chichewa; Chewa; Nyanja" },
"zh": { "name": "Chinese" },
"co": { "name": "Corsican" },
"hr": { "name": "Croatian" },
"cs": { "name": "Czech" },
"da": { "name": "Danish" },
"dv": { "name": "Divehi; Dhivehi; Maldivian;" },
"nl": { "name": "Dutch" },
"en": { "name": "English" },
"eo": { "name": "Esperanto" },
"et": { "name": "Estonian" },
"ee": { "name": "Ewe" },
"fi": { "name": "Finnish" },
"fr": { "name": "French" },
"gl": { "name": "Galician" },
"ka": { "name": "Georgian" },
"de": { "name": "German" },
"el": { "name": "Greek, Modern" },
"gn": { "name": "Guaraní" },
"gu": { "name": "Gujarati" },
"ht": { "name": "Haitian; Haitian Creole" },
"ha": { "name": "Hausa" },
"he": { "name": "Hebrew (modern)" },
"hi": { "name": "Hindi" },
"hu": { "name": "Hungarian" },
"id": { "name": "Indonesian" },
"ga": { "name": "Irish" },
"ig": { "name": "Igbo" },
"is": { "name": "Icelandic" },
"it": { "name": "Italian" },
"ja": { "name": "Japanese" },
"jv": { "name": "Javanese" },
"kn": { "name": "Kannada" },
"kk": { "name": "Kazakh" },
"km": { "name": "Khmer" },
"rw": { "name": "Kinyarwanda" },
"ky": { "name": "Kirghiz, Kyrgyz" },
"ko": { "name": "Korean" },
"ku": { "name": "Kurdish" },
"la": { "name": "Latin" },
"lb": { "name": "Luxembourgish, Letzeburgesch" },
"lg": { "name": "Luganda" },
"ln": { "name": "Lingala" },
"lo": { "name": "Lao" },
"lt": { "name": "Lithuanian" },
"lv": { "name": "Latvian" },
"mk": { "name": "Macedonian" },
"mg": { "name": "Malagasy" },
"ms": { "name": "Malay" },
"ml": { "name": "Malayalam" },
"mt": { "name": "Maltese" },
"mi": { "name": "Māori" },
"mr": { "name": "Marathi (Marāṭhī)" },
"mn": { "name": "Mongolian" },
"ne": { "name": "Nepali" },
"no": { "name": "Norwegian" },
"om": { "name": "Oromo" },
"or": { "name": "Oriya" },
"pa": { "name": "Panjabi, Punjabi" },
"fa": { "name": "Persian" },
"pl": { "name": "Polish" },
"ps": { "name": "Pashto, Pushto" },
"pt": { "name": "Portuguese" },
"qu": { "name": "Quechua" },
"ro": { "name": "Romanian, Moldavian, Moldovan" },
"ru": { "name": "Russian" },
"sa": { "name": "Sanskrit (Saṁskṛta)" },
"sd": { "name": "Sindhi" },
"sm": { "name": "Samoan" },
"sr": { "name": "Serbian" },
"gd": { "name": "Scottish Gaelic; Gaelic" },
"sn": { "name": "Shona" },
"si": { "name": "Sinhala, Sinhalese" },
"sk": { "name": "Slovak" },
"sl": { "name": "Slovene" },
"so": { "name": "Somali" },
"st": { "name": "Southern Sotho" },
"es": { "name": "Spanish; Castilian" },
"su": { "name": "Sundanese" },
"sw": { "name": "Swahili" },
"sv": { "name": "Swedish" },
"ta": { "name": "Tamil" },
"te": { "name": "Telugu" },
"tg": { "name": "Tajik" },
"th": { "name": "Thai" },
"ti": { "name": "Tigrinya" },
"tk": { "name": "Turkmen" },
"tl": { "name": "Tagalog" },
"tr": { "name": "Turkish" },
"ts": { "name": "Tsonga" },
"tt": { "name": "Tatar" },
"ug": { "name": "Uighur, Uyghur" },
"uk": { "name": "Ukrainian" },
"ur": { "name": "Urdu" },
"uz": { "name": "Uzbek" },
"vi": { "name": "Vietnamese" },
"cy": { "name": "Welsh" },
"fy": { "name": "Western Frisian" },
"xh": { "name": "Xhosa" },
"yi": { "name": "Yiddish" },
"yo": { "name": "Yoruba" }
}
// Translator.js
import React, { useState } from 'react'
import './Translator.css'
import languageList from './language.json';
export default function Translator() {
const [inputFormat, setInputFormat] = useState('en');
const [outputFormat, setOutputFormat] = useState('hi');
const [translatedText, setTranslatedText] = useState('Translation');
const [inputText, setInputText] = useState('');
const handleReverseLanguage = () => {
const value = inputFormat;
setInputFormat(outputFormat);
setOutputFormat(value);
setInputText('');
setTranslatedText('Translation');
}
const handleRemoveInputText = () => {
setInputText('');
setTranslatedText('Translation');
}
const handleTranslate = async () => {
if (!inputText || !inputFormat || !outputFormat) return;
document.querySelector('.fa.fa-spinner.fa-spin').style.display = "block";
document.querySelector('.translate').style.display = 'none';
const url =
`https://microsoft-translator-text.p.rapidapi.com/translate?to%5B0%5D=${outputFormat}&api-version=3.0&profanityAction=NoAction&textType=plain`;
const options = {
method: 'POST',
headers: {
'content-type': 'application/json',
'X-RapidAPI-Key': {"YOUR_API_KEY"},
'X-RapidAPI-Host': 'microsoft-translator-text.p.rapidapi.com'
},
body: JSON.stringify([
{
Text: inputText
}
])
};
try {
const response = await fetch(url, options);
const result = await response.text();
const responseObject = JSON.parse(result);
const translation = responseObject[0].translations[0].text;
setTranslatedText(translation);
} catch (error) {
console.log(error);
alert("Please Try Again! Some Error Occurred at your side");
}
document.querySelector('.fa.fa-spinner.fa-spin').style.display = "none";
document.querySelector('.translate').style.display = 'block';
}
return (
<div className="container">
<div className="row1">
<select value={inputFormat}
onChange={(e) => setInputFormat(e.target.value)}>
{Object.keys(languageList).map((key, index) => {
const language = languageList[key];
return (
<option key={index} value={key}>{language.name}</option>
);
})}
</select>
<svg className='reversesvg'
onClick={handleReverseLanguage}
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24">
<path d=
"M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z">
</path>
</svg>
<select value={outputFormat} onChange={(e) => {
setOutputFormat(e.target.value);
setTranslatedText('Translation');
}}>
{Object.keys(languageList).map((key, index) => {
const language = languageList[key];
return (
<option key={index + 118} value={key}>{language.name}</option>
);
})}
</select>
</div>
<div className="row2">
<div className="inputText">
<svg className='removeinput'
style={{ display: (inputText.length) ? "block" : "none" }}
onClick={handleRemoveInputText}
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24">
<path d=
"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z">
</path>
</svg>
<textarea type="text"
value={inputText}
placeholder='Enter Text'
onChange={(e) => setInputText(e.target.value)} />
</div>
<div className="outputText">{translatedText}</div>
</div>
<div className="row3">
<button className='btn'
onClick={handleTranslate}>
<i className="fa fa-spinner fa-spin"></i>
<span className='translate'>Translate</span>
</button>
</div>
</div>
)
}
CSS
/* Translator.css */
body {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.container {
display: flex;
align-items: center;
min-height: 100vh;
flex-direction: column;
box-sizing: border-box;
padding-top: 50px;
}
.row1 {
width: calc(100% - 10px);
max-width: 650px;
}
select {
width: calc(50% - 20px);
line-height: 40px;
font-size: 14px;
border: 1px solid #dadce0;
border-radius: 8px;
height: 40px;
padding-left: 18px;
position: relative;
color: #1a0dab;
cursor: pointer;
outline: none;
user-select: none;
}
.reversesvg {
width: 20px;
color: rgba(0, 0, 0, 0.26);
line-height: 40px;
opacity: 0.5;
vertical-align: middle;
cursor: pointer;
margin: 0px 10px;
}
option {
color: #202124;
}
.row2 {
display: flex;
justify-content: space-between;
align-items: center;
width: calc(100% - 10px);
max-width: 650px;
margin-top: 10px;
position: relative;
}
.inputText {
width: calc(50% - 20px);
position: relative;
}
.outputText {
width: calc(50% - 20px);
height: 169px;
font-family: monospace;
box-sizing: border-box;
padding: 15px;
font-size: 20px;
border-radius: 8px;
overflow: auto;
background: #edeff0;
text-align: left;
}
.row2 textarea {
width: 100%;
height: 150px;
resize: none;
box-sizing: border-box;
padding: 0px 35px 10px 10px;
margin-top: 15px;
border: none;
font-size: 20px;
overflow: auto;
color: #202124;
outline: none;
}
.removeinput {
cursor: pointer;
width: 20px;
position: absolute;
opacity: 0.5;
top: 5px;
right: 3px;
}
.row3 {
width: calc(100% - 10px);
max-width: 650px;
margin-top: 15px;
margin-bottom: 20px;
}
.btn {
width: 100%;
position: relative;
padding: 10px;
outline: none;
background-color: #6d9eed;
color: #fff;
border: 2px solid #6d9eed;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
letter-spacing: 0.5px;
}
.btn i {
display: none;
}
@media screen and (max-width: 500px) {
.row2 {
flex-direction: column;
}
.inputText {
width: 100%;
}
.outputText {
width: 100%;
margin-top: 20px;
}
}
::-webkit-scrollbar {
width: 4px;
}
::-webkit-scrollbar-track {
display: none;
}
::-webkit-scrollbar-thumb {
background: rgb(173, 172, 172);
border-radius: 4px;
}
运行应用程序的步骤:
步骤1: 在终端中输入以下命令。
npm start
步骤2: 打开网页浏览器并键入以下URL
http://localhost:3000/
输出: