Build Fun Translation App with React
Tags: react
Published: 2021-03-05 10:42:52

![App Preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iy7k90110l38gslt9jo0.png)
###### [Source Code](https://github.com/touhidulShawan/fun-translation)
###### [Live Preview](https://touhidulshawan.github.io/fun-translation/#/)

# 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
```js
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")
);
```
- Create 6 different navigation item for our translator type like 
**yoda, minion, dothraki, valyrian, mandaloriyan, shakespeare** 

`NavBar.jsx`
```js
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;

```

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

export default NavItem;

```
- Now setup  route for all the components 
`App.jsx`
```js
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;
```
- create custom hooks that will handle our userInput Text on all 6 different components [ **Yoda, Minion, Dothraki, Valyrian, Mandalorian, Shakespeare** ] 

`useTranslateText.jsx`
```js
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];
};
```
- Create a TextField Component that will be responsible to take user input

`TextField.jsx`
```js
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;
```
---
- Now Create all 6 types of translator components
`**Yoda.jsx**`
```js
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;
```

`**Minion.jsx**`
```js
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;

```

`**Dothraki.jsx**`
```js
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;
```
`**Valyrian.jsx**`
```js
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;
```
`**Mandalorian.jsx**`
```js
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;
```
`**Shakespeare.jsx**`
```js
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;
```
---
> All done. Now App is good to go. 
> For style the app I use [Tailwindcss](tailwindcss.com/)
> Fun Translation API [Fun Translation API](https://funtranslations.com/api/)