React Wars

🚀 May the 4th is rapidly approaching and having recently (re) learned the basics of React, I created a simple app that explores the Star Wars API. The end result is available for your perusal in https://github.com/esmitperez/react-wars.

React Wars Crawl

React + React Hooks = 💕

The app consists of 2 functional (a.k.a pure) components: Films and Crawl. In order to share data between components I am relying on Context using a useContext() hook which reads a context previously created using React.createContext({}).

    <MovieContext.Provider value={{episode: currMovie, dispatch: movieSwitchDispatch}}>
        <div className="App-toolbar">
            <Films></Films>
        </div>

        <Crawl episode="IV"/>
    </MovieContext.Provider>

Application initialization lifecycle:

  1. Upon first-load, Films component connects to https://swapi.dev/api/films/ to obtain the movie list using a useEffect() hook. You can think of a useEffect hook as a function that has a side effect, the side effect we want in this case, is to connect to the API using fetch and populate a data structure we can later use.
  2. The list of movies is then exposed via a useState() provided function, this function is capable of performing state changes allowing react to re-render all things that have changed and need to be re-drawn on the real HTML DOM.
  3. When a movie is clicked, movieSwitcherCtx.dispatch function exposed via useContext() is called, this updates the current episode
  4. Component Crawl also has a useEffect(), which triggers on changes to the episode field in movieSwitcherCtx, this is invoked when the dispatch method is called in the Films component.
  5. A new call to SW API is done, this time to the specific movie endpoint, and the corresponding fields are updated and we have a crawl!

The Crawl

I found a really good implementation for the crawl, good enough to showcase the result of the above API calls, however, the timing was a bit off, based on All 7 Star Wars Opening Crawls (HD) I determined the duration should be 11s:


.star-wars__crawl-section .crawl {
  position: relative;
  top: 99999px;
  transform-origin: 50% 100%;
  animation: crawl 80s linear;
}

@keyframes crawl {
  0% {
    top: -100px;
    transform: rotateX(20deg) translateZ(0);
  }
  100% {
    top: -6000px;
    transform: rotateX(25deg) translateZ(-2500px);
  }
}

Da Font

Finally, what good would it be if things didn’t at least look a bit …rebelious? Star Jedi V2 Font is a pretty official looking font, and adding it is easy:

  1. Add a <link> to your HTML:
<link href="//db.onlinewebfonts.com/c/0c724f6aa457310440cf8949c615cbd7?family=Star+Jedi" rel="stylesheet" type="text/css"/>
  1. Bring in the externally hosted font:
@import url(//db.onlinewebfonts.com/c/0c724f6aa457310440cf8949c615cbd7?family=Star+Jedi);

@font-face {font-family: "Star Jedi"; src: url("//db.onlinewebfonts.com/t/0c724f6aa457310440cf8949c615cbd7.eot"); src: url("//db.onlinewebfonts.com/t/0c724f6aa457310440cf8949c615cbd7.eot?#iefix") format("embedded-opentype"), url("//db.onlinewebfonts.com/t/0c724f6aa457310440cf8949c615cbd7.woff2") format("woff2"), url("//db.onlinewebfonts.com/t/0c724f6aa457310440cf8949c615cbd7.woff") format("woff"), url("//db.onlinewebfonts.com/t/0c724f6aa457310440cf8949c615cbd7.ttf") format("truetype"), url("//db.onlinewebfonts.com/t/0c724f6aa457310440cf8949c615cbd7.svg#Star Jedi") format("svg"); }

  1. And apply!
.App-header {
  font-family: "Star Jedi";
  font-size: 400%;
}