This repo has outdated dependencies, if you are intrested in this repo, let me know (by open an issue) and I will updated its dependencies and some concepts.
Welcome to the fantastic land of pure functions, monads and love.
Below you will find some exercise how to use functional and reactive programing with React.
Oh, one more thing before we start; If you see any typos or errors, please let me know! β With that being said, let's code some fine javascript (or typescript).
- Clone the project:
$ git clone https://github.com/tjoskar/react-fp-workshop.git react-fp-workshop
- Install dependencies:
$ cd react-fp-workshop
$ npm install
- Boot up the application:
$ node fuse.js
- Navigate to
http://localhost:8080
All right! Give you self a high five π
Typescript, or JavaScript
β Prince Hamlet
All you need is a typescript aware editor, like vscode and you are all set.
- Option 1: Check out the branch 'JavaScript':
git checkout javascript
- Option 2: Changing extension on all ts files to js.
Now you need a great js editor and you are good to go.
OBS! Chapter 6, 7 and 8 will only work with typescript
β― tree -I 'node_modules' .
.
βββ fuse.js // Config for fuse box
βββ index.html
βββ package-lock.json
βββ package.json
βββ readme.md // This file. Woop Woop!
βββ src // The source folder
β βββ boot.ts // Application endpont, the start of everything
β βββ components
β β βββ search // Contains components for the search page
β β β βββ search-field.ts
β β β βββ search-result.ts
β β β βββ search.ts
β β βββ shows // Contains components for upcoming shows
β β βββ show.ts
β β βββ shows.ts
β β βββ upcoming-shows.ts
β βββ either.ts // See Chapter 7
β βββ store // Contains redux store
β βββ search
β β βββ index.ts
β β βββ search.actions.ts
β β βββ search.epic.ts
β β βββ search.reducer.ts
β β βββ test // See Chapter 6
β β βββ search.epic.test.ts
β βββ shows
β β βββ index.ts
β β βββ show.actions.ts
β β βββ show.epic.ts
β β βββ show.reducer.ts
β βββ store.ts
βββ tsconfig.json
8 directories, 24 files
Browse the code and get a feeling about how it works.
Navigate to http://localhost:8080
and click on search. Search for your favorite tv series. Did you find it? No? Open up the dev tools to see what is going on.
Exercise: Implement the logic for the search in search.epic.ts
Criteria:
- Make sure to not search if the search term is less than 3 characters. (tips: filter)
- Wait for 500ms before making the search (tips: debounceTime)
- Cancel the ongoing ajax request if the user wants to make a new one (tips: switchMap). You can check in the dev tools to see if the ajax request is cancelled or not.
tips: Check in: DebounceTime, SwitchMap, MergeMap, Filter, Map, MapTo
If we unsubscribe for all shows, it is pretty empty on the first page. Create a new component and show that one when the user doesnβt have subscribed to any series.
Use recomposes branch for this. You can take a look how it is done in search-result.ts
Subscribe on an ongoing show. Did you notice that "Next episode:" is always empty?
Exercise: Calculate the next episode and print that one. Put the logic in components/shows/show.ts
for simplicity.
Criteria:
- Do not use any if statement (nor conditional operator
?:
), instead, use a Maybe monad.
It can sometimes take a while before we get a search result.
Exercise: Add a lodging text to inform the user that we are loading.
Tips: create a new property (loading
) in the search store (store/search/search.reducer.ts
). Set it to true
for UPDATE_SEARCH_FIELD
actions and false
for UPDATE_SEARCH_RESULT
.
Criteria:
- Use
branch
(and mayberenderComponent
and/orrenderNothing
)
Go to the search page. Go offline (you can simulate this in your browsers dev tools). Search for your favorite tv show.
Did you find your show? Of course not, we are offline. Okay, let's go online again and search again. β What!? Still no result?
Exercise: Handle ajax failure.
Go through the code to see what you would like to test.
I'm using jest
and you can run the test case by npm test
(do it!)
Take a look at src/either.ts
. How could you rewrite the code to use the Either monad instead?
Tips: you can run the code with: npx ts-node src/either.ts
Let's say we want to get all validation errors at once, how can you do that? (tips: use a validation "monad")