Kako sam izgradio vremensku aplikaciju u freeCodeCampu koristeći React i Typescript

Tako sam se napokon odlučio vratiti na freeCodeCamp i pokušati završiti svoj certifikat o razvoju. Već sam bio završio sve algoritme i vodiče početkom prošle godine, a nedostajali su samo projekti.

Ali sada, kad imam više iskustva kao programer Full Stacka, većina projekata pomalo je lagana za moju trenutnu razinu. Tako sam imao dva izbora. Mogao bih se ili vratiti osnovama i sve ih završiti u danu, ili bih mogao ubiti dvije ptice jednim kamenom: zabaviti se i eksperimentirati s tehnologijom dok radim na tim projektima. Odlučio sam se za ovo drugo.

Ali napravimo to tri ptice - jer već neko vrijeme želim napisati stvar sa tutorialima / vodičima. Danas ćemo se pozabaviti projektom Pokaži lokalno vrijeme. Ali ovaj put kombinirat će React i Typescript! Gotov kôd možete pogledati u ovom GitHub repo-u, kao i demonstraciju uživo ovdje.

Pozadina

Prvo je prvo: zašto bih to želio raditi? Pa evo u čemu je stvar: već neko vrijeme skačem naprijed-natrag s Angular 5 i React. I više mi se sviđa React kao okvir. Mali je i sažet, ali ima sve značajke koje su vam potrebne za stvaranje potpuno funkcionalne aplikacije s jednom stranicom. Što se tiče Angular-a, on je prevelik da bih mogao uživati ​​u njemu tako maloj aplikaciji ... ali koristi Typescript!

TypeScript je super skup JavaScript koji dodaje puno značajki koje nedostaju JavaScriptu, čak i uz poboljšanja iz ES6 / 7. Najviše je poznato po statičnom tipkanju. Pa sam se pitao mogu li dobiti najbolje od oba svijeta. Odgovor je bio odlučan DA! ... Redux nije uključen. (Mislim da možete uključiti Redux, ali dosad je bilo mučno postavljati ga, pa to neću raditi za ovaj vodič.)

Za ovaj ćemo se projekt usredotočiti na najmanji minimum korisničkih priča, jer je moj fokus tehnologija, a ne bilo kakve dodatne značajke. Kao takav, API koji ćemo koristiti za ovu aplikaciju bit će Wunderround. Savršeno je za ono što gradimo, jer nude temperature u Fahrenheitu i Celzijusu, a nude i ikone za različite vremenske uvjete. To znači manje programskog rada na našem kraju.

Korak 0: Postavljanje

Koristit ću create-react-appza ovaj projekt prilagođenu React skriptu za Typescript kako bismo zadržali nultu konfiguraciju i jednostavnost upotrebe. Dobar članak o postavljanju React aplikacije s TypeScriptom napisao je Trey Huffine i može se naći ovdje.

Svakako predlažem da pogledate taj post za još detaljnih postavki. Ali bez daljnjeg pokretanja, u terminalu ćemo pokrenuti sljedeći redak.

create-react-app weather --scripts-version=react-scripts-tsnpm install --save core-decorators

Do dekoratora ću doći malo kasnije. Samo znajte da je to zgodna mala značajka koju sam zaista oduševio isprobati. Ali da bismo je mogli koristiti, morat ćemo urediti našu tsconfig.jsondatoteku tako da uključuje eksperimentalne dekoratere. Da biste to učinili, samo dodajte podebljani redak koda.

{ "compilerOptions": {// ...code hidden... "noUnusedLocals": true, "experimentalDecorators": true } // ...more code hidden...}

A budući da sam Prettier instalirao na svoje razvojno okruženje, morao sam promijeniti tslint.jsondatoteku jer se lint sukobio s programom za formatiranje. Ako ste postavili sličan razvoj, predlažem da samo izbrišete sva pravila tslint, tako da ne morate zapetljati konfiguraciju. Datoteka bi trebala izgledati ovako nakon što završite.

Struktura mape koju ću koristiti izgledat će ovako. Datoteke možete stvarati, brisati i premještati u skladu s tim.

weather-app/├─ .gitignore├─ node_modules/├─ public/├─ src/ └─ assets/ | - - loader.svg | - - logo.svg └─ components/ | - - Weather.tsx | - - WeatherDisplay.tsx └─ styles/ | - - App.css | - - WeatherDisplay.css | — — index.tsx | — — registerServiceWorker.ts | — — App.tsx | — — index.css | - - config.ts | - - types.ts├─ package.json├─ tsconfig.json├─ tsconfig.test.json└─ tslint.json

Dobro, najgore je prošlo! Napokon smo postavili našu aplikaciju. Zaronimo u kod.

Korak 1: oblikovanje

Prvo želim maknuti stajling. Nisam baš neki dizajner, pa sam sve što sam zapravo učinio ponovno create-react-appizdefinirao zadane stilove kako bi imao zelenu temu freeCodeCamp. Uz to sam gumb učinio više sličnim gumbu i naravno, zelenijim. Slobodno možete podivljati s tim ako ste slučajno CSS majstor. Ovdje također možete preuzeti slikovne datoteke i smjestiti ih u svoju assets/mapu.

Korak 2: Dobro, lagao sam ... Još postavki

Ali ne brinite, ovo je stvarni kôd ovaj put. Prvo započnimo s jednostavnim dijelom: dodavanjem API-ja i API ključeva. Ovdje nema ništa novo - do sada izgleda točno poput uobičajenog JavaScript-a.

Sada za specifičnu stvar TypeScript, moramo navesti tipove. Pa, ne moramo, ali definitivno bismo trebali. Razlog statičnog tipkanja je taj što nam daje sigurnost. Za razliku od uobičajenog JavaScript-a, naš se kôd neće pokretati ako su stvari pogrešne vrste. U osnovi to znači da nam kompajler koji se jednostavno izjasnio neće dopustiti da napišemo loš kod.

Kao što vidite, nije previše zastrašujuće. Samo dodajte tip nakon dvotačke. Primitivni tipovi (string, number, boolean) podržani su izvan vrata. S objektima je dobra ideja stvoriti novi tip specifičan za taj određeni objekt kao što se vidi u WeatherDatas DisplayLocation.

Sad sam bio malo lijen, jer je oblik podataka koji dolaze iz našeg API-ja puno veći, i mogao sam stvoriti cijeli objekt. No odlučio sam uzeti samo ono što mi je trebalo, a ostalo odbaciti, zbog čega je ova types.tsdatoteka toliko mala koliko i jest.

Korak 3: Reagirajte - zabavni dio

Idem preskacu index.tsxi App.tsxdatoteke jer postoji stvarno ništa zaista novo tamo. Samo znajte da se uvoz razlikuje zbog toga koliko je TypeScript strog prema modulima. Umjesto toga, prvo ćemo pregledati prezentacijsku komponentu.

Još uvijek preferiram destrukturu Componenti FragmentReact, umjesto pozivanja React.Component, jer to smanjuje suvišnost. A za Fragmente, ako se nikada prije niste igrali s njima, to je u osnovi div koji se ne pojavljuje u HTML oznakama.

Također ćete primijetiti da sam na vrh dodao sučelja. Sučelje određuje kako bi trebali izgledati naši rekviziti i stanje. A ako niste primijetili, trik TypeScript-a svemu dodaje vrste, pa se to događa iznad kutnih zagrada te>. If you are familiar with prop types, it does the same thing, but I feel like this is much cleaner.

The next thing is the weird @ symbol. Well, that’s a decorator! I originally wanted to hook up Redux and connect so that I can show a much more complicated version, but the autobind will do for now.

A decorator is basically a function that wraps around the class and applies necessary attributes. It also allows us to use export default at the top, which is just a personal preference of mine.

@decorateexport default Class {}
// is the same as
export default decorate(Class)

In this case autobind will, as the name entails, automatically bind this to everything so we don’t have to worry about binding issues. And coming from a more Object Oriented language, these class methods will look a lot cleaner than the JavaScript work-around with the arrow functions.

classMethod = () => { console.log('when you use arrows, you don't have to worry about the keyword "this"');}
classMethod () { console.log('because of javascript, you have to worry about the keyword "this" here');}

And now finally we move to the bulk of our logic, which is going to be living in the Weather.tsx component.

The first thing you’ll notice is the ? in the interface. I mentioned that we definitely should define types for our props, but what happens when you know for certain it won’t be defined until after the API call? Well we can define optional types with a question mark.

What is happening in the background is that the variable weatherData is only allowed to be a WeatherData type or undefined. Also, remember that our WeatherData type is only a subsection of what wunderground offers. Earlier I mentioned that we are only going to take the data that we needed from the API — well, that’s what that huge destructuring on line 55 is doing.

Did I mention you can specify expected return types of functions? That’s what is happening here with getCurrentPosition , because I wanted to make sure that it returns a promise.

The reasoning here is that I didn’t want to call getCurrentWeather until after we had the correct geolocation, which means we’re dealing with asynchronous events. Async always means Promises, so that’s what’s going to happen.

A word of warning: the native geolocation API does take a long time to get a result without passing in any options. I opted to not add options to it as it was giving me errors at the time.

And I believe that is all the new things happening in this app because of TypeScript. Everything else should be familiar if you know React. But hopefully you can see the benefits of this superset, as it adds both security to our code as well as some nice super powers.

Step 4: Complete!

You did it! You finished an app that shows the weather at your current position. And in doing so, you’ve covered a good chunk of TypeScript as well as incorporating it into React.

Of course, there can definitely be improvements on this, like an option to search and show other locations. And the UI can definitely be worked on. But if you haven’t already finished the weather app on freeCodeCamp, you have already gone above and beyond on this assignment.