DEV Community

Cover image for Build Fun Translation App with React
Touhidul Shawan
Touhidul Shawan

Posted on

Build Fun Translation App with React

App Preview

Source Code
Live Preview

What is it?

This app takes some text as input from the user then translates it according to character language. Suppose we want to translate some text to minion's language then

  1. We have to select the Minion option from the home page first
  2. Then we have to enter our expected text in the textbox field
  3. Then we have to submit the form then it will be translated by expected character language

Steps

  • Create a new react app called funtranslation with
    npx create-react-app funtranslation

  • Add react-router-dom for our navigation

    yarn add react-router-dom or
    npm install react-router-dom

  • Wrap BrowserRounter in index.js file

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { BrowserRouter as Router } from "react-router-dom";

ReactDOM.render(
  <Router>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </Router>,
  document.getElementById("root")
);
Enter fullscreen mode Exit fullscreen mode
  • Create 6 different navigation item for our translator type like yoda, minion, dothraki, valyrian, mandaloriyan, shakespeare

NavBar.jsx

import NavItem from "./NavItem";

const NavBar = () => {
  return (
    <nav>
      <ul>
        <NavItem path="/yoda" linkName="Yoda" />
        <NavItem path="/minion" linkName="Minion" />
        <NavItem path="/dothraki" linkName="Dothraki" />
        <NavItem path="/valyrian" linkName="Valyrian" />
        <NavItem path="/mandalorian" linkName="Mandalorian" />
        <NavItem path="/shakespeare" linkName="Shakespeare" />
      </ul>
    </nav>
  );
};

export default NavBar;

Enter fullscreen mode Exit fullscreen mode

NavItem.jsx

import { NavLink } from "react-router-dom";
const NavItem = ({ path, linkName }) => {
  return <NavLink to={path}>{linkName}</NavLink>;
};

export default NavItem;

Enter fullscreen mode Exit fullscreen mode
  • Now setup route for all the components App.jsx
import { Route, Switch } from "react-router-dom";
import Home from "./containers/Home";
import Yoda from "./containers/Yoda";
import Minion from "./containers/Minion";
import Dothraki from "./containers/Dothraki";
import Valyrian from "./containers/Valyrian";
import Mandalorian from "./containers/Mandalorian";
import Shakespeare from "./containers/Shakespeare";

const App = () => {
  return (
    <Switch>
      <Route path="/" exact component={Home} />
      <Route path="/yoda" exact component={Yoda} />
      <Route path="/minion" exact component={Minion} />
      <Route path="/dothraki" exact component={Dothraki} />
      <Route path="/valyrian" exact component={Valyrian} />
      <Route path="/mandalorian" exact component={Mandalorian} />
      <Route path="/shakespeare" exact component={Shakespeare} />
    </Switch>
  );
};
export default App;
Enter fullscreen mode Exit fullscreen mode
  • create custom hooks that will handle our userInput Text on all 6 different components [ Yoda, Minion, Dothraki, Valyrian, Mandalorian, Shakespeare ]

useTranslateText.jsx

import { useReducer, useState, useEffect } from "react";

const textReducer = (state, action) => {
  switch (action.type) {
    case "ENTER_TEXT":
      return action.payload.text;
    default:
      return state;
  }
};

export const useTranslateText = (translator) => {
  const [textToTranslate, dispatch] = useReducer(textReducer, "");
  const [translatedContent, setTranslatedContent] = useState({});

  useEffect(() => {
    let isActive = true;
    const startTranslation = async () => {
      if (textToTranslate !== "") {
        const response = await fetch(
          `https://api.funtranslations.com/translate/${translator}.json?text=${textToTranslate}`
        );
        const data = await response.json();
        const content = await { ...data.contents };
        if (isActive) {
          setTranslatedContent(content);
        }
      }
    };
    startTranslation();
    return () => {
      isActive = false;
    };
  }, [textToTranslate, translator]);

  return [translatedContent, dispatch];
};
Enter fullscreen mode Exit fullscreen mode
  • Create a TextField Component that will be responsible to take user input

TextField.jsx

import { useState } from "react";

const TextField = ({ dispatch }) => {
  const [userText, setUserText] = useState("");

  const handleChange = (evt) => {
    setUserText(evt.target.value);
  };

  const handleSubmit = (evt) => {
    evt.preventDefault();
    dispatch({ type: "ENTER_TEXT", payload: { text: userText } });
    setUserText("");
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        onChange={handleChange}
        placeholder="Enter your text here"
        max={50}
        value={userText}
      />
      <button type="submit">Translate</button>
    </form>
  );
};

export default TextField;
Enter fullscreen mode Exit fullscreen mode

  • Now Create all 6 types of translator components **Yoda.jsx**
import TranslateCard from "../components/TranslateCard";
import { useTranslateText } from "../customHooks/useTranslateText";
import TextField from "./TextField";
import Layout from "../components/Layout";

const Yoda = () => {
  const [translatedContent, dispatch] = useTranslateText("yoda");
  return (
    <Layout>
      <TextField dispatch={dispatch} />
      {translatedContent.translated ? (
        <TranslateCard {...translatedContent} />
      ) : null}
    </Layout>
  );
};
export default Yoda;
Enter fullscreen mode Exit fullscreen mode

**Minion.jsx**

import TranslateCard from "../components/TranslateCard";
import { useTranslateText } from "../customHooks/useTranslateText";
import TextField from "./TextField";
import Layout from "../components/Layout";

const Minion = () => {
  const [translatedContent, dispatch] = useTranslateText("minion");
  return (
    <Layout>
      <TextField dispatch={dispatch} />
      {translatedContent.translated ? (
        <TranslateCard {...translatedContent} />
      ) : null}
    </Layout>
  );
};
export default Minion;

Enter fullscreen mode Exit fullscreen mode

**Dothraki.jsx**

import TranslateCard from "../components/TranslateCard";
import { useTranslateText } from "../customHooks/useTranslateText";
import TextField from "./TextField";
import Layout from "../components/Layout";

const Dothraki = () => {
  const [translatedContent, dispatch] = useTranslateText("dothraki");
  return (
    <Layout>
      <TextField dispatch={dispatch} />

      {translatedContent.translated ? (
        <TranslateCard {...translatedContent} />
      ) : null}
    </Layout>
  );
};
export default Dothraki;
Enter fullscreen mode Exit fullscreen mode

**Valyrian.jsx**

import TranslateCard from "../components/TranslateCard";
import { useTranslateText } from "../customHooks/useTranslateText";
import TextField from "./TextField";
import Layout from "../components/Layout";

const Valyrian = () => {
  const [translatedContent, dispatch] = useTranslateText("valyrian");
  return (
    <Layout>
      <TextField dispatch={dispatch} />
      {translatedContent.translated ? (
        <TranslateCard {...translatedContent} />
      ) : null}
    </Layout>
  );
};
export default Valyrian;
Enter fullscreen mode Exit fullscreen mode

**Mandalorian.jsx**

import TranslateCard from "../components/TranslateCard";
import { useTranslateText } from "../customHooks/useTranslateText";
import TextField from "./TextField";
import Layout from "../components/Layout";

const Mandalorian = () => {
  const [translatedContent, dispatch] = useTranslateText("mandalorian");
  return (
    <Layout>
      <TextField dispatch={dispatch} />
      {translatedContent.translated ? (
        <TranslateCard {...translatedContent} />
      ) : null}
    </Layout>
  );
};
export default Mandalorian;
Enter fullscreen mode Exit fullscreen mode

**Shakespeare.jsx**

import TranslateCard from "../components/TranslateCard";
import { useTranslateText } from "../customHooks/useTranslateText";
import TextField from "./TextField";
import Layout from "../components/Layout";

const Shakespeare = () => {
  const [translatedContent, dispatch] = useTranslateText("shakespeare");
  return (
    <Layout>
      <TextField dispatch={dispatch} />
      {translatedContent.translated ? (
        <TranslateCard {...translatedContent} />
      ) : null}
    </Layout>
  );
};
export default Shakespeare;
Enter fullscreen mode Exit fullscreen mode

All done. Now App is good to go.
For style the app I use Tailwindcss
Fun Translation API Fun Translation API

Top comments (0)