Repl
https://repl.it/@ianmstew/FrightenedFlusteredExam
Codesandbox
- Users App (exercise): https://codesandbox.io/s/wo6yo6o0kk
- Users App (completed): https://codesandbox.io/s/508yx02q3l
Intro to Coding
Repl
https://repl.it/@ianmstew/FrightenedFlusteredExam
Codesandbox
Intro to Coding
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Logical
| (() => { | |
| function MappedYieldGenerator(generator, mapYield) { | |
| return function*() { | |
| const gen = generator(); | |
| let genResult; | |
| let resolvedValue; | |
| do { | |
| genResult = gen.next(resolvedValue); | |
| resolvedValue = yield mapYield(genResult.value); | |
| } while (!genResult.done); |
So another 🤯 about TypeScript. We use plain objects as arbitrary maps all the time, but TypeScript deems that usage (correctly) too flexible.
const map = {};
map.foo = 'foo'; // Error: Property 'foo' does not exist on type '{}'.Okay, then we need to type our object as a map:
| /* Loader that renders empty unless `props.active` is true */ | |
| function Loader(props) { | |
| const { active } = props; | |
| return active && <div>Loading...</div>; | |
| } | |
| /* Loader class component that renders empty until a timeout */ | |
| class LoaderWithDelay extends React.Component { |
| (() => { | |
| function getLocale() { | |
| // IE 11 does not support navigator.languages | |
| return navigator.languages ? navigator.languages[0] : navigator.language; | |
| } | |
| function isTimezoneSupported(timezone) { | |
| try { | |
| new Date().toLocaleDateString(getLocale(), { timeZone: timezone }); | |
| } catch (err) { | |
| if (err instanceof RangeError) { |
TypeScript makes JavaScript classes actually useful ^^
By fixing a fatal ES6 class flaw
The conspicuous absence of a way to reference constructor arguments within inline class property initializers
Which IMO after a year of struggles completely hobbles ES6 classes
const toggleButtonProps = {
key: index,
selected
};
if (props.disabled) toggleButtonProps.disabled = props.disabled;Hot tip!! Try to challenge yourself to not imperatively update an object or array when you can use ES6 syntax to declare your logic at initialization/object creation time. The progression of developer into declarative/functional programming looks like this:
| // Parallel implementation to Avatar example from | |
| // https://github.com/conorhastings/use-reducer-with-side-effects/blob/19d097e95302068d8368b0a10b379b0a6bab9f93/README.md | |
| import { useObserver, useLocalStore } from 'mobx-react'; | |
| // WIP library inspired by `import { promisedComputed } from 'async-computed-mobx'` | |
| import asyncComputed from 'utils/mobx/asyncComputed'; | |
| const DEFAULT_AVATAR = '/assets/img/default-avatar.png'; | |
| function Avatar(props: { userName: string }) { |
| // Type and Factory | |
| type RecordX = ReturnType<typeof RecordX>; | |
| function RecordX( | |
| id: string, | |
| props?: Record<string, string[]> | |
| ) { | |
| return Object.assign({ id }, props); | |
| } |