├── .eslintrc.json ├── .gitignore ├── README.md ├── SUMMARY.md ├── _layouts └── website │ └── page.html ├── basic-react-components.md ├── basic-react-components ├── 6.1.md ├── 6.10.md ├── 6.2.md ├── 6.3.md ├── 6.4.md ├── 6.5.md ├── 6.6.md ├── 6.7.md ├── 6.8.md └── 6.9.md ├── book.json ├── cover.jpg ├── images └── XFEJxkXPVs.gif ├── myIntro.md ├── package-lock.json ├── package.json ├── react-advanced-setup.md ├── react-advanced-setup ├── 2.1.md ├── 2.2.md └── 2.3.md ├── react-basic-setup.md ├── react-basic-setup ├── 3.1.md ├── 3.2.md ├── 3.3.md └── 3.4.md ├── react-jsx.md ├── react-jsx ├── 5.1.md ├── 5.2.md ├── 5.3.md ├── 5.4.md ├── 5.5.md ├── 5.6.md ├── 5.7.md └── 5.8.md ├── react-nodes.md ├── react-nodes ├── 4.1.md ├── 4.2.md ├── 4.3.md ├── 4.4.md ├── 4.5.md ├── 4.6.md └── 4.7.md ├── react-props.md ├── react-props ├── 7.1.md ├── 7.2.md ├── 7.3.md ├── 7.4.md ├── 7.5.md └── 7.6.md ├── react-semantics.md ├── react-state.md ├── react-state ├── 8.1.md ├── 8.2.md ├── 8.3.md └── 8.4.md ├── scripts └── pathway.js ├── styles ├── ebook.css └── website.css ├── template.md ├── test.js └── what-is-react.md /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "parserOptions": { 8 | "ecmaFeatures": { 9 | "experimentalObjectRestSpread": true, 10 | "jsx": true 11 | }, 12 | "sourceType": "module" 13 | }, 14 | "plugins": [ 15 | "react" 16 | ], 17 | "rules": { 18 | "linebreak-style": [ 19 | "error", 20 | "unix" 21 | ], 22 | "quotes": [ 23 | "error", 24 | "single" 25 | ], 26 | "semi": [ 27 | "error", 28 | "always" 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Node rules: 2 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 3 | .grunt 4 | 5 | ## Dependency directory 6 | ## Commenting this out is preferred by some people, see 7 | ## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git 8 | node_modules 9 | 10 | # Book build output 11 | _book 12 | 13 | # eBook build output 14 | *.epub 15 | *.mobi 16 | *.pdf 17 | *.DS_Store 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Enlightenment 2 | 3 | Written by [Cody Lindley](http://codylindley.com/) sponsored by — [Frontend Masters](https://frontendmasters.com/) 4 | 5 | Learn React in the terse cookbook style found with previous Enlightenment titles (i.e., [jQuery Enlightenment](http://jqueryenlightenment.com/), [JavaScript Enlightenment](http://javascriptenlightenment.com/), [DOM Enlightenment](http://domenlightenment.com/)) 6 | 7 | *** 8 | 9 | **Read Online At**: 10 | 11 | * [reactenlightenment.com](http://www.reactenlightenment.com/) 12 | 13 | *** 14 | 15 | Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. 16 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [1. What Is React](what-is-react.md) 4 | * [2. React Semantics/Terminology](react-semantics.md) 5 | * [3. React & Babel Basic Setup](react-basic-setup.md) 6 | * [3.1 Using react.js & react-dom.js](react-basic-setup/3.1.md) 7 | * [3.2 Using JSX via Babel](react-basic-setup/3.2.md) 8 | * [3.3 Using ES6 & ES* with React](react-basic-setup/3.3.md) 9 | * [3.4 Writing React With JSFiddle](react-basic-setup/3.4.md) 10 | * [4. React Nodes](react-nodes.md) 11 | * [4.1 What Is a React Node?](react-nodes/4.1.md) 12 | * [4.2 Creating React Nodes](react-nodes/4.2.md) 13 | * [4.3 Rendering to DOM](react-nodes/4.3.md) 14 | * [4.4 Defining Node Attributes/Props](react-nodes/4.4.md) 15 | * [4.5 Inlining CSS on Element Nodes](react-nodes/4.5.md) 16 | * [4.6 Using Built-in Element Factories](react-nodes/4.6.md) 17 | * [4.7 Defining React Node Events](react-nodes/4.7.md) 18 | * [5. JavaScript Syntax Extension (a.k.a., JSX)](react-jsx.md) 19 | * [5.1 What Is a JSX?](react-jsx/5.1.md) 20 | * [5.2 Creating React Nodes With JSX](react-jsx/5.2.md) 21 | * [5.3 Rendering JSX to DOM](react-jsx/5.3.md) 22 | * [5.4 Using JS Expressions in JSX](react-jsx/5.4.md) 23 | * [5.5 Using JS Comments in JSX](react-jsx/5.5.md) 24 | * [5.6 Using Inline CSS in JSX](react-jsx/5.6.md) 25 | * [5.7 Defining JSX Attributes/Props](react-jsx/5.7.md) 26 | * [5.8 Defining Events in JSX](react-jsx/5.8.md) 27 | * [6. Basic React Components](basic-react-components.md) 28 | * [6.1 What Is a React Component?](basic-react-components/6.1.md) 29 | * [6.2 Creating Components](basic-react-components/6.2.md) 30 | * [6.3 Return One Starting Node/Component](basic-react-components/6.3.md) 31 | * [6.4 Referring to a Component Instance](basic-react-components/6.4.md) 32 | * [6.5 Defining Events on Components](basic-react-components/6.5.md) 33 | * [6.6 Composing Components](basic-react-components/6.6.md) 34 | * [6.7 Grokking Component Lifecycle's](basic-react-components/6.7.md) 35 | * [6.8 Accessing Children Components/Nodes](basic-react-components/6.8.md) 36 | * [6.9 Using ref Attribute](basic-react-components/6.9.md) 37 | * [6.10 Re-rendering A Component](basic-react-components/6.10.md) 38 | * [7. React Component Props](react-props.md) 39 | * [7.1 What Are Component Props?](react-props/7.1.md) 40 | * [7.2 Sending Component Props](react-props/7.2.md) 41 | * [7.3 Getting Component Props](react-props/7.3.md) 42 | * [7.4 Setting Default Component Props](react-props/7.4.md) 43 | * [7.5 Component Props More Than Strings](react-props/7.5.md) 44 | * [7.6 Validating Component Props](react-props/7.6.md) 45 | * [8. React Component State](react-state.md) 46 | * [8.1 What Is Component State?](react-state/8.1.md) 47 | * [8.2 Working with Component State](react-state/8.2.md) 48 | * [8.3 State vs. Props](react-state/8.3.md) 49 | * [8.4 Creating Stateless Function Components](react-state/8.4.md) 50 | -------------------------------------------------------------------------------- /_layouts/website/page.html: -------------------------------------------------------------------------------- 1 | {% extends template.self %} 2 | 3 | {% block body %} 4 |
5 | 8 |
9 | Get free, lifetime access to 5 popular courses 10 |
11 | 12 |
13 | 14 | {{ super() }} 15 | 16 | 29 | 30 | {% endblock %} 31 | -------------------------------------------------------------------------------- /basic-react-components.md: -------------------------------------------------------------------------------- 1 | # Basic React Components 2 | 3 | This chapter will show how React nodes are used to create basic React components. 4 | -------------------------------------------------------------------------------- /basic-react-components/6.1.md: -------------------------------------------------------------------------------- 1 | # What Is a React Component? 2 | 3 | The next section will provide a mental model around the nature of a React component and cover details around creating React components. 4 | 5 | Typically a single view of a user interface (e.g., the tree or trunk) is divided up into logical chunks (e.g., branches). The tree becomes the starting component (e.g., a layout component) and then each chunk in the UI will become a sub-component that can be divided further into sub components (i.e., sub-branches). This not only keeps the UI [organized](https://facebook.github.io/react/docs/thinking-in-react.html#step-1-break-the-ui-into-a-component-hierarchy) but it also allows data and state changes to logically flow from the tree, to branches, then sub branches. 6 | 7 | If this description of React components is cryptic then I would suggest that you examine any application interface and mentally start dividing the UI into logical chunks. Those chunks potentially are components. React components are the programatic abstraction (i.e., UI, events/interactions, state changes, DOM changes) making it possible to literally create these chunks and sub-chunks. For example, a lot of application UI's will have a layout component as the top component in a UI view. This component will contain several sub-components, like maybe, a search component or a menu component. The search component can then be divided further into sub-components. Maybe the search input is a separate component from the button that invokes the search. As you can see, a UI can quickly become a [tree of components](https://facebook.github.io/react/docs/thinking-in-react.html#step-1-break-the-ui-into-a-component-hierarchy). Today, software UI's are typically created by crafting a tree of very simple [single responsibility](https://en.wikipedia.org/wiki/Single_responsibility_principle) components. React provides the means to create these components via the `React.createClass()` function (or, `React.Component` if using ES6 classes). The `React.createClass()` function takes in a configuration object and returns a React component instance. 8 | 9 | A React component is basically any part of a UI that can contain React nodes (via `React.createElement()` or JSX). I spent a lot of time up front talking about React nodes so that the ingredients of a React component would be firmly understood. Sounds simple until one realizes that React components can contained other React sub-components which can result in a complex tree of components. This is not unlike the idea that React nodes can contain other React nodes in a Virtual DOM. It might hurt your brain, but if you think hard about it all a component does it wraps itself around a logical set of branches from a tree of nodes. In this sense, you define an entire UI from components using React but the result is a tree of React nodes that can easily be translated to something like an HTML document (i.e., tree of DOM nodes that produces a UI). 10 | -------------------------------------------------------------------------------- /basic-react-components/6.10.md: -------------------------------------------------------------------------------- 1 | # Re-rendering A Component 2 | 3 | You likely realize that calling `ReactDom.render()` is the initial kicking off of the rendering of a component and all sub components. 4 | 5 | After the initial mounting of components, a re-rendering will occur when: 6 | 7 | 1. A component's `setState()` method is called 8 | 2. A component's `forceUpdate()` method is called 9 | 10 | Anytime a component is re-rendered (or initially rendered) all of its children components are rendered inside of the virtual DOM possibly causing a change to the real DOM (i.e., the UI). The distinction I am making here is that just because a component is re-rendered in the virtual DOM, it does not always follow that an update to the DOM will occur. 11 | 12 | In the code example below `ReactDOM.render(< App / >, app);` starts the first cascade of rendering, rendering `` and ``. The next re-render occurs when the `setInterval()` calls the `setState()` component method, which causes `` and `` to be re-rendered. Note the UI changes when the `now` state is changed. 13 | 14 | > [source code](https://jsfiddle.net/codylindley/ewewfxg0/#tabs=js,result,html,resources) 15 | 16 | The next re-render occurs when the `setTimeout()` is invoked and `this.forceUpdate()` is called. Note that simply updating the state (i.e., `this.state.now = 'foo';`) does not cause a re-render. I set the state using `this.state`, and then I have to call `this.forceUpdate()` so the component will re-render with the new state. 17 | 18 | ***NEVER UPDATE THE STATE USING `this.state.`, DID IT HERE TO SHOW USE OF `this.forceUpdate()`.*** 19 | -------------------------------------------------------------------------------- /basic-react-components/6.2.md: -------------------------------------------------------------------------------- 1 | # Creating React components 2 | 3 | A React component that will potentially contain `state` can be created by calling the `React.createClass()` function. This function takes one argument object used to specify the details of the component. The available component configuration options are listed below (a.k.a., component specifications). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 |
render()A required value, typically a function that returns React nodes, other React components, or null/false
getInitialState()Function which returns an object containing initial value of this.state
getDefaultProps()Function which returns an object containing values to be set on this.props
propTypesObject containing validation specifications for props
mixins Array of mixins (object containing methods) that can be share among components
statics Object containing static methods
displayNameString, naming the component, used in debugging messages. If using JSX this is set automatically.
componentWillMount()Callback function invoked once immediately before the initial rendering occurs
componentDidMount()Callback function invoked immediately after the initial rendering occurs
componentWillReceiveProps()Callback function invoked when a component is receiving new props
shouldComponentUpdate()Callback function invoked before rendering when new props or state are being received
componentWillUpdate()Callback function invoked immediately before rendering when new props or state are being received.
componentDidUpdate()Callback function invoked immediately after the component's updates are flushed to the DOM
componentWillUnmount()Callback function invoked immediately before a component is unmounted from the DOM
76 | 77 | The most important component configuration option is `render`. This configuration option is required and is a function that returns React nodes and components. All other component configurations are optional. 78 | 79 | The following code is an example of creating a `Timer` React component from React nodes using `React.createClass()`. 80 | 81 | Make sure you read the comments in the code. 82 | 83 | > [source code](https://jsfiddle.net/12u58fjb/#tabs=js,result,html,resources) 84 | 85 | It looks like a lot of code. However, the bulk of the code simply involves creating a `` component and then passing the `createClass()` function creating the component a configuration object containing 5 properties (`getInitialState`, `tick`, `componentDidMount`, `componentWillUnmount`, `render`). 86 | 87 | Notice that `Timer` is capitalized. When creating custom React components you need to capitalize the name of the component. Additionally, the value `this` among the configuration options refers to the component instance created. We'll discuss the component API in more detail at the end of this chapter. For now, just meditate on the configuration options available when defining a React component and how a reference to the component is achieved using the `this` keyword. Also note, that in the code example above I added my own custom instance method (i.e., `tick`) during the creation of the `` component. 88 | 89 | Once a component is mounted (i.e., created) you can use the component API. The api contains four methods. 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 110 | 113 | 114 | 115 | 116 | 121 | 122 | 123 | 124 | 125 | 130 | 131 | 132 | 133 | 134 | 139 | 140 | 141 |
API methodExampleDescription
setState() 100 | 101 | this.setState({mykey: 'my new value'}); 102 | 103 |

104 | 105 | this.setState(function(previousState, currentProps) { 106 | return {myInteger: previousState.myInteger + 1}; 107 | }); 108 | 109 |
111 | Primary method used to re-render a component and sub components. 112 |
replaceState() 117 | 118 | this.replceState({mykey: 'my new value'}); 119 | 120 | Like setState() but does not merge old state just deletes it uses new object sent.
forceUpdate() 126 | 127 | this.forceUpdate(function(){//callback}); 128 | 129 | Calling forceUpdate() will cause render() to be called on the component, skipping shouldComponentUpdate().
isMounted() 135 | 136 | this.isMounted() 137 | 138 | isMounted() returns true if the component is rendered into the DOM, false otherwise.
142 | 143 | The most commonly used component API method is `setState()`. Its usage will be covered in the React Component State chapter. 144 | 145 | #### Notes 146 | 147 | * The component callback configuration options (`componentWillUnmount`, `componentDidUpdate`, `componentWillUpdate`, `shouldComponentUpdate`, `componentWillReceiveProps`, `componentDidMount`, `componentWillMount`) are also known as "lifecycle methods" because these various methods are executed at specific points in a component's life. 148 | * The `React.createClass()` function is a convenience function that creates component instances for you (via JavaScript `new` keyword). 149 | * The `render()` function should be a pure function. Which means: 150 | 151 | >it does not modify component state, it returns the same result each time it's invoked, and it does not read from or write to the DOM or otherwise interact with the browser (e.g., by using `setTimeout`). If you need to interact with the browser, perform your work in `componentDidMount()` or the other lifecycle methods instead. Keeping `render()` pure makes server rendering more practical and makes components easier to think about. 152 | -------------------------------------------------------------------------------- /basic-react-components/6.3.md: -------------------------------------------------------------------------------- 1 | # Components Return One Node/Component 2 | 3 | The `render` configuration value defined when creating a component should return only one React node (or, component). This one node/component can contain any number of children. In the code below the `` is the starting node. Inside of this node any number of sibling and child nodes can be returned. 4 | 5 | > [source code](https://jsfiddle.net/fv26rjdL/#tabs=js,result,html,resources) 6 | 7 | Note that if you want to return React nodes on more than one line (taking advantage of whitespace) you will have to surround the returned value in `()`. In the code below the JSX defining (i.e., rendered) the `MyComponent` is returned in `()`. 8 | 9 | > [source code](https://jsfiddle.net/e2awasnk/#tabs=js,result,html,resources) 10 | 11 | An error will occur if more than one starting React node is attempted to be returned. If you think about it, the error occurs because returning two `React.createElement()` functions isn't possible with JavaScript. 12 | 13 | > [source code](https://jsfiddle.net/xe5kkpub/#tabs=js,result,html,resources) 14 | 15 | Thus, the above code will result in the following error: 16 | 17 | ``` 18 | babel.js:62789 Uncaught SyntaxError: embedded: Adjacent JSX elements must be wrapped in an enclosing tag (10:3) 19 | 8 | return ( 20 | 9 | test 21 | > 10 | test 22 | | ^ 23 | 11 | ); 24 | 12 | } 25 | 13 | }); 26 | ``` 27 | 28 | Commonly, developers will add a wrapping element `
` element to avoid this error. 29 | 30 | This issue also concerns components. Just like React nodes, if you are returning a component, only one starting component can be returned but that component can have unlimited children. 31 | 32 | > [source code](https://jsfiddle.net/o0fqta42/#tabs=js,result,html,resources) 33 | 34 | If you return two sibling components, the same error will occur. 35 | 36 | > [source code](https://jsfiddle.net/3968zzv3/#tabs=js,result,html,resources) 37 | 38 | ``` 39 | VM7370 babel.js:62789 Uncaught SyntaxError: embedded: Adjacent JSX elements must be wrapped in an enclosing tag (10:2) 40 | 8 | return ( 41 | 9 | 42 | > 10 | 43 | | ^ 44 | 11 | ); 45 | 12 | } 46 | 13 | }); 47 | ``` 48 | -------------------------------------------------------------------------------- /basic-react-components/6.4.md: -------------------------------------------------------------------------------- 1 | # Referring to a Component Instance 2 | 3 | When a component is `render`'ed', a React component instance is created from the passed configuration options. One can gain access to this instance and it's properties (e.g., `this.props`) and methods (e.g., `this.setState()`) in two ways. 4 | 5 | The first way is by using the `this` keyword from within a configuration function option. In the code example below all of the `console.log(this)` statements will refer to the component instance. 6 | 7 | > [source code](https://jsfiddle.net/codylindley/xkz0ph2d/4/#tabs=js,result,html,resources) 8 | 9 | The other way to gain a reference to a component instance involves making use of the return value from calling `ReactDOM.render()`. In other words, the `ReactDOM.render()` function will return a reference to the top most rendered component. 10 | 11 | > [source code](https://jsfiddle.net/codylindley/vavk9b5t/2/#tabs=js,result,html,resources) 12 | 13 | #### Notes 14 | 15 | * The `this` keyword will commonly be used from within a component to access instance properties like `this.props.[NAME OF PROP]`, `this.props.children`, and `this.state`,. It will also be used to call class methods/properties, that all components share like `this.setState` and `this.replaceState()`. 16 | -------------------------------------------------------------------------------- /basic-react-components/6.5.md: -------------------------------------------------------------------------------- 1 | # Defining Events on Components 2 | 3 | Events can be added to React nodes inside of a components `render` configuration option (discussed in Ch. 4 section 4.7 and Ch. 5 section 5.8). 4 | 5 | In the code example, two React events (i.e., `onClick` & `onMouseOver`) are set on React nodes (via JSX) using what looks like component props. 6 | 7 | > [source code](https://jsfiddle.net/sjL64ogk/#tabs=js,result,html,resources) 8 | 9 | Basically, React when rendering a component looks for special React prop events (e.g., `onClick`) and treats these props differently from other props (all React events shown in table below). Obviously the difference being, that eventing in the real DOM is being wired up behind the scenes. 10 | 11 | Part of this wiring is auto binding the context of the handler/callback to the scope of the component instance. In the code example below the value of `this` inside of the handlers/callbacks will reference the component instance itself. 12 | 13 | > [source code](https://jsfiddle.net/gke6vmc9/#tabs=js,result,html,resources) 14 | 15 | React supports the following events and event specific syntheticEvent properties: 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 64 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 98 | 99 | 100 | 101 | 102 | 106 | 107 | 108 | 109 | 110 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 138 | 139 | 140 | 141 | 142 | 143 | 148 | 149 | 150 |
Event Type/Category:Events:Event Specific Properties:

Clipboard

onCopy, onCut, onPasteDOMDataTransfer, clipboardData

Composition

onCompositionEnd, onCompositionStart, onCompositionUpdatedata

Keyboard

onKeyDown, onKeyPress, onKeyUpaltKey, 37 | charCode, 38 | ctrlKey, 39 | getModifierState(key), 40 | key, 41 | keyCode, 42 | locale, 43 | location, 44 | metaKey, 45 | repeat, 46 | shiftKey, 47 | which

Focus

onChange, onInput, onSubmitDOMEventTarget, relatedTarget

Form

onFocus, onBlur

Mouse

onClick, onContextMenu, onDoubleClick, onDrag, onDragEnd, onDragEnter, onDragExit 62 | onDragLeave, onDragOver, onDragStart, onDrop, onMouseDown, onMouseEnter, onMouseLeave 63 | onMouseMove, onMouseOut, onMouseOver, onMouseUpaltKey, 65 | button, 66 | buttons, 67 | clientX, 68 | clientY, 69 | ctrlKey, 70 | getModifierState(key), 71 | metaKey, 72 | pageX, 73 | pageY, 74 | DOMEventTarget relatedTarget, 75 | screenX, 76 | screenY, 77 | shiftKey, 78 |

Selection

onSelect

Touch

onTouchCancel, onTouchEnd, onTouchMove, onTouchStart 89 | altKey 90 | DOMTouchList changedTouches, 91 | ctrlKey, 92 | getModifierState(key), 93 | metaKey, 94 | shiftKey, 95 | DOMTouchList targetTouches, 96 | DOMTouchList touches, 97 |

UI

onScroll 103 | detail, 104 | DOMAbstractView view 105 |

Wheel

onWheel 111 | deltaMode, 112 | deltaX, 113 | deltaY, 114 | deltaZ, 115 |

Media

onAbort, onCanPlay, onCanPlayThrough, onDurationChange, onEmptied, onEncrypted, onEnded, onError, onLoadedData, onLoadedMetadata, onLoadStart, onPause, onPlay, onPlaying, onProgress, onRateChange, onSeeked, onSeeking, onStalled, onSuspend, onTimeUpdate, onVolumeChange, onWaiting

Image

onLoad, onError

Animation

onAnimationStart, onAnimationEnd, onAnimationIteration 134 | animationName, 135 | pseudoElement, 136 | elapsedTime 137 |

Transition

onTransitionEnd 144 | propertyName, 145 | pseudoElement, 146 | elapsedTime 147 |
151 | 152 | #### Notes 153 | 154 | * React normalizes events so that they behave consistently across different browsers. 155 | * Events in React are triggered on the bubbling phase. To trigger an event on the capturing phase add the word "Capture" to the end of the event name (e.g., `onClick` would become `onClickCapture`). 156 | * If you need the browser event details for a given event you can access this by using the `nativeEvent` property found in the SyntheticEvent object passed into React event hander/callbacks. 157 | * React does not actually attach events to the nodes themselves, it uses [event delegation](http://domenlightenment.com/#11.14). 158 | * `e.stopPropagation()` or `e.preventDefault()` should be triggered manually to [stop](http://domenlightenment.com/#11.9) event [propagation](http://domenlightenment.com/#11.10) instead of `returning false;`. 159 | * Not all DOM events are provided by React. But you can still make use of them [using React lifecycle methods](https://facebook.github.io/react/tips/dom-event-listeners.html). 160 | -------------------------------------------------------------------------------- /basic-react-components/6.6.md: -------------------------------------------------------------------------------- 1 | # Composing Components 2 | 3 | If it is not obvious React components can make use of other React components. That is, when defining a component the `render` configuration function can contain references to other components. When a component contains another component it can be said that the parent component owns the child component (aka composition). 4 | 5 | In the code below the `BadgeList` component contains/owns the `BadgeBill` and `BadgeTom` component. 6 | 7 | > [source code](https://jsfiddle.net/codylindley/0m9s4ow7/#tabs=js,result,html,resources) 8 | 9 | This code was purposefully simplistic in order to demonstrate component composition. In the next chapter, we will look at how the code will typically be written making use of props to create a generic `Badge` component. The generic Badge component can take any name value v.s. creating a unique badge and hard coding the name in the component. 10 | 11 | ### Notes 12 | 13 | * A key tenet of maintainable UI are composable components. React components by design are meant to contain other React components. 14 | * Notice how HTML and previously defined components are mixed together in the `render()` configuration function. 15 | -------------------------------------------------------------------------------- /basic-react-components/6.7.md: -------------------------------------------------------------------------------- 1 | # Grokking Component Lifecycle's 2 | 3 | React components live certain life events that are called lifecycle events. These lifecycle's events are tied to lifecycle methods. I discussed several of these methods at the start of this chapter when discussing the creation of components. 4 | 5 | The lifecycle methods provide hooks into the phases and the nature of a component. In the code example, taken from section 6.2, I am console logging the occurrence of the lifecycle events `componentDidMount`, `componentWillUnmount`, and `getInitialState` lifecycle methods. 6 | 7 | > [source code](https://jsfiddle.net/codylindley/s3v614b3/#tabs=js,result,html,resources) 8 | 9 | The methods can be divided into three categories (Mounting, Updating, and Unmounting phases). 10 | 11 | Below I show a table for each category and the containing lifecycle methods. 12 | 13 | ###Mounting Phase (happens once in a components life): 14 | 15 | > "The first phase of the React Component life cycle is the Birth/Mounting phase. This is where we start initialization of the Component. At this phase, the Component's props and state are defined and configured. The Component and all its children are mounted on to the Native UI Stack (DOM, UIView, etc.). Finally, we can do post-processing if required. The Birth/Mounting phase only occurs once." - [React In-depth](https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/introduction.html) 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
MethodDescription

getInitialState()

is invoked before a component is mounted. Stateful components should implement this and return the initial state data.

componentWillMount()

is invoked immediately before mounting occurs.

componentDidMount()

is invoked immediately after mounting occurs. Initialization that requires DOM nodes should go here.

34 | 35 | ###Updating Phase (happens over and over in a components life): 36 | 37 | > "The next phase of the life cycle is the Growth/Update phase. In this phase, we get new props, change state, handle user interactions and communicate with the component hierarchy. This is where we spend most of our time in the Component's life. Unlike Birth or Death, we repeat this phase over and over." - [React In-depth](https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/introduction.html) 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 59 | 60 |
MethodDescription

componentWillReceiveProps(object nextProps)

is invoked when a mounted component receives new props. This method should be used to compare this.props and nextProps to perform state transitions using this.setState().

shouldComponentUpdate(object nextProps, object nextState)

is invoked when a component decides whether any changes warrant an update to the DOM. Implement this as an optimization to compare this.props with nextProps and this.state with nextState and return false if React should skip updating.

componentWillUpdate(object nextProps, object nextState)

is invoked immediately before updating occurs. You cannot call this.setState() here.

componentDidUpdate(object prevProps, object prevState)

is invoked immediately after updating occurs. 58 |

61 | 62 | ###Unmounting Phase (happens once in a components life): 63 | 64 | > "The final phase of the life cycle is the Death/Unmount phase. This phase occurs when a component instance is unmounted from the Native UI. This can occur when the user navigates away, the UI page changes, a component is hidden (like a drawer), etc. Death occurs once and readies the Component for Garbage Collection." - [React In-depth](https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/introduction.html) 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 |
MethodDescription

componentWillUnmount()

is invoked immediately before a component is unmounted and destroyed. Cleanup should go here.

75 | 76 | ### Notes 77 | 78 | * `componentDidMount` and `componentDidUpdate`are good places to put other libraries' logic. 79 | * Read [React In-depth](https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/introduction.html) for a detailed look into the React component lifecycle events 80 | * Mounting Phase follows this order: 81 |
    82 |
  1. Initialize / Construction
  2. 83 |
  3. getDefaultProps() (React.createClass) or MyComponent.defaultProps (ES6 class)
  4. 84 |
  5. getInitialState() (React.createClass) or this.state = ... (ES6 constructor)
  6. 85 |
  7. componentWillMount()
  8. 86 |
  9. render()
  10. 87 |
  11. Children initialization & life cycle kickoff
  12. 88 |
  13. componentDidMount()
  14. 89 |
90 | * Updating Phase follows this order: 91 |
    92 |
  1. componentWillReceiveProps()
  2. 93 |
  3. shouldComponentUpdate()
  4. 94 |
  5. componentWillUpdate()
  6. 95 |
  7. render()
  8. 96 |
  9. Children Life cycle methods
  10. 97 |
  11. componentDidUpdate()
  12. 98 |
99 | * Unmount Phase follows this order: 100 |
    101 |
  1. componentWillUnmount()
  2. 102 |
  3. Children Life cycle methods
  4. 103 |
  5. Instance destroyed for Garbage Collection
  6. 104 |
105 | -------------------------------------------------------------------------------- /basic-react-components/6.8.md: -------------------------------------------------------------------------------- 1 | # Accessing Children Components/Nodes 2 | 3 | If a component, when used, contains child React components or React nodes inside of the component (e.g., `` or `test`) these React node or component instances can be accessed by using `this.props.children`. 4 | 5 | In the code below the `Parent` component when used, contains two `
` React node children, which contains React text nodes. All of the children instances, inside of the component are accessible using `this.props.children`. In the code below I access these children inside of the `Parent` `componentDidMount` lifecycle function. 6 | 7 | > [source code](https://jsfiddle.net/codylindley/z7u11n44/#tabs=js,result,html,resources) 8 | 9 | The `this.props.children` of the `Parent` component instance returns an array containing the references to the child React node instances. This array is logged out to the console. Additionally, in the `Parent` component I am logging out the child of the first `
` (i.e., a text node). 10 | 11 | Note how when I use the `Parent2` component inside of the `Parent` component the child React node of `Parent2` only contains one `` React node (i.e., `child2text`). Thus, `this.props.children` used in `componentDidMount` lifecycle function for `Parent2` component will be a direct reference to this `` React node (i.e., not an array containing a single reference). 12 | 13 | Given that `this.props.children` can potentially contain a wide set of nodes and components React provides a set of utilities to deal with this data structure. These utilities are listed below. 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
UtilitieDescription

React.Children.map(this.props.children, function(){})

Invoke fn on every immediate child contained within children with this set to thisArg. If children is a keyed fragment or array it will be traversed: fn will never be passed the container objects. If children is null or undefined returns null or undefined rather than an array.

React.Children.forEach(this.props.children, function(){})

Like React.Children.map() but does not return an array.

React.Children.count(this.props.children)

Return the total number of components in children, equal to the number of times that a callback passed to map or forEach would be invoked.

React.Children.only(this.props.children)

Return the only child in children. Throws otherwise.

React.Children.toArray(this.props.children)

Return the children opaque data structure as a flat array with keys assigned to each child. Useful if you want to manipulate collections of children in your render methods, especially if you want to reorder or slice this.props.children before passing it down.

41 | 42 | ### Notes 43 | 44 | * When there is only a single child, `this.props.children` will be the single child component itself without the array wrapper. This saves an array allocation. 45 | * It can be [confusing](https://facebook.github.io/react/tips/children-undefined.html) at first to realize that `children` are not what a component returns, but instead what is contained inside of component anywhere (including in a `render`) it is instantiated. 46 | -------------------------------------------------------------------------------- /basic-react-components/6.9.md: -------------------------------------------------------------------------------- 1 | # Using `ref` Attribute 2 | 3 | The `ref` attribute makes it possible to store a reference to a particular React element or component returned by the component `render()` configuration function. This can be valuable when you need a reference, from within a component, to some element or component contained within the `render()` function. 4 | 5 | To make a reference, place the `ref` attribute with a function value on any React element or component. Then, inside of the function, the first parameter within the scope of the function will be a reference to the element or component the `ref` is on. 6 | 7 | For example in the code below I am console logging the reference out for each `ref`. 8 | 9 | > [source code](https://jsfiddle.net/codylindley/2oj6x0o6/#tabs=js,result,html,resources) 10 | 11 | Notice (see console) that references to components return component instances while references to React elements return a reference to the actual DOM element in the HTML DOM (i.e., not a reference to the virtual DOM, but the actual HTML DOM). 12 | 13 | A common use for `ref`'s are to store a reference on the component instance. In the code below I use the `ref` callback function on the text `` to store a reference on the component instance so other instance methods have access to the reference via `this` (i.e., `this.textInput.focus()`). 14 | 15 | > [source code](https://jsfiddle.net/codylindley/ttfh7mdh/#tabs=js,result,html,resources) 16 | 17 | ### Notes 18 | 19 | * Refs can't be attached to a stateless function because the component does not have a backing instance. 20 | * You might see a `ref` attribute with a string instead of a function; this is called a string `ref` and will likely be deprecated in the future. Function `ref`s are preferred. 21 | * The `ref` callback function is called immediately after the component is mounted. 22 | * References to a component instance allow one to call custom methods on the component if any are exposed when defining it. 23 | * Writing refs with inline function expressions means React will see a different function object on every update, `ref` will be called with null immediately before it's called with the component instance. I.e., when the referenced component is unmounted and whenever the `ref` changes, the old `ref` will be called with `null` as an argument. 24 | * React makes two suggestions when using refs: "Refs are a great way to send a message to a particular child instance in a way that would be inconvenient to do via streaming Reactive props and state. They should, however, not be your go-to abstraction for flowing data through your application. By default, use the Reactive data flow and save refs for use cases that are inherently non-reactive." and "If you have not programmed several apps with React, your first inclination is usually going to be to try to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. Placing the state there often eliminates any desire to use refs to "make things happen" – instead, the data flow will usually accomplish your goal." 25 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "structure": { 3 | "readme": "myIntro.md" 4 | }, 5 | "plugins": [ "jsfiddle"], 6 | "pluginsConfig": { 7 | "jsfiddle":{ 8 | "type":"script", 9 | "tabs":["js","result","html","resources"], 10 | "height": "500", 11 | "width": "100%" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrontendMasters/react-enlightenment/71e8c3f3af47a448f6577097401c8e1790b454fe/cover.jpg -------------------------------------------------------------------------------- /images/XFEJxkXPVs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrontendMasters/react-enlightenment/71e8c3f3af47a448f6577097401c8e1790b454fe/images/XFEJxkXPVs.gif -------------------------------------------------------------------------------- /myIntro.md: -------------------------------------------------------------------------------- 1 | # React Enlightenment 2 | 3 | Written by [Cody Lindley](http://codylindley.com/) sponsored by — [Frontend Masters](https://frontendmasters.com/) 4 | 5 | Learn React in the terse cookbook style found with previous Enlightenment titles (i.e., [jQuery Enlightenment](http://jqueryenlightenment.com/), [JavaScript Enlightenment](http://javascriptenlightenment.com/), [DOM Enlightenment](http://domenlightenment.com/)) 6 | 7 | *** 8 | 9 | **Read Online At**: 10 | 11 | * [reactenlightenment.com](http://www.reactenlightenment.com/) 12 | 13 | **download a .pdf, .epub, or .mobi file from**: 14 | 15 | * [https://www.gitbook.com/book/frontendmasters/react-enlightenment/details](https://www.gitbook.com/book/frontendmasters/react-enlightenment/details) 16 | 17 | **contribute content, suggestions, and fixes on github**: 18 | 19 | * [https://github.com/FrontendMasters/react-enlightenment](https://github.com/FrontendMasters/react-enlightenment) 20 | 21 | *** 22 | 23 | Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-enlightenment", 3 | "version": "1.0.0", 4 | "description": "Written by [Cody Lindley](http://codylindley.com/) sponsored by — [Frontend Masters](https://frontendmasters.com/)", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "honkit serve", 8 | "build": "honkit build" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/FrontendMasters/react-enlightenment.git" 13 | }, 14 | "author": "", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/FrontendMasters/react-enlightenment/issues" 18 | }, 19 | "homepage": "https://github.com/FrontendMasters/react-enlightenment#readme", 20 | "devDependencies": { 21 | "eslint": "^8.45.0", 22 | "eslint-config-standard": "^17.1.0", 23 | "eslint-plugin-promise": "^6.1.1", 24 | "eslint-plugin-react": "^7.33.0", 25 | "eslint-plugin-standard": "^4.1.0", 26 | "gitbook-plugin-jsfiddle": "^1.0.3", 27 | "honkit": "^5.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /react-advanced-setup.md: -------------------------------------------------------------------------------- 1 | # React Setup 2 | 3 | This section of will discuss setting up React for development. 4 | 5 | The chapter is broken down into the following sections. 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /react-advanced-setup/2.1.md: -------------------------------------------------------------------------------- 1 | # Title [Use Title-Casing] 2 | 3 | ## Sub [Use Title-Casing] -------------------------------------------------------------------------------- /react-advanced-setup/2.2.md: -------------------------------------------------------------------------------- 1 | # Title [Use Title-Casing] 2 | 3 | ## Sub [Use Title-Casing] -------------------------------------------------------------------------------- /react-advanced-setup/2.3.md: -------------------------------------------------------------------------------- 1 | # Title [Use Title-Casing] 2 | 3 | ## Sub [Use Title-Casing] -------------------------------------------------------------------------------- /react-basic-setup.md: -------------------------------------------------------------------------------- 1 | # React Setup 2 | 3 | This section will discuss setting up an HTML page so that when it is parsed by a web browser, at runtime, the browser can transform JSX expressions and correctly run React code. 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /react-basic-setup/3.1.md: -------------------------------------------------------------------------------- 1 | # Using `react.js` and `react-dom.js` in an HTML Page 2 | 3 | The `react.js` file is the core file needed to create React elements and write react components. When you intend to render your components in an HTML document (i.e., the DOM) you'll also need the `react-dom.js` file. The `react-dom.js` file is dependent on the `react.js` file and must be included after first including the `react.js` file. 4 | 5 | An example of an HTML document properly including React is shown below. 6 | 7 | ```html 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ``` 18 | 19 | With the `react.js` file and `react-dom.js` file loaded into an HTML page it is then possible to create React nodes/components and then render them to the DOM. In the HTML below a `HelloMessage` React component is created containing a React `
` node that is rendered to the DOM inside of the `
` HTML element. 20 | 21 | ```html 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 39 | 40 | 41 | ``` 42 | 43 | This setup is all you need to use React. However this setup does not make use of JSX. The next section will discuss JSX usage. 44 | 45 | #### Notes 46 | 47 | * An alternative `react.js` file called `react-with-addons.js` is available [containing a collection of utility modules](https://facebook.github.io/react/docs/addons.html) for building React applications. The "addons" file can be used in place of the `react.js` file. 48 | * Don't make the `` element the root node for your React app. Always put a root `
` into ``, give it an ID, and render into it. This gives React its own pool to play in without worrying about what else potentially wants to make changes to the children of the `` element. 49 | -------------------------------------------------------------------------------- /react-basic-setup/3.2.md: -------------------------------------------------------------------------------- 1 | # Using JSX via Babel 2 | 3 | The creation of the React `HelloMessage` component and React `
` element node in the HTML page below was done using the `React.createClass()` and `React.createElement()` functions. This code should look familiar as it is identical to the HTML from the previous section. This HTML will run without errors in [ES5 browsers](https://kangax.github.io/compat-table/es5/). 4 | 5 | ```html 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 23 | 24 | 25 | ``` 26 | 27 | Optionally, by using JSX via Babel, it is possible to simplify the creation of React elements by abstracting the `React.createElement()` JavaScript function calls so they can be written in a more natural HTML-like style and syntax. 28 | 29 | Instead of writing the following, which uses `React.createElement()`: 30 | 31 | ```javascript 32 | return React.createElement('div',null,'Hello ',this.props.name); 33 | ``` 34 | 35 | Using JSX, you can write this: 36 | 37 | ```javascript 38 | return
Hello {this.props.name}
; 39 | ``` 40 | 41 | And then Babel will convert it back to the code which uses `React.createElement()` so it can be parsed by a JavaScript engine. 42 | 43 | Loosely stated you can consider JSX a form of HTML that you can directly write in JavaScript that requires a transformation step, done by Babel, into ECMAScript 5 code that browsers can run. 44 | 45 | More will be said about JSX in the JSX chapter. For now, just realize that JSX is an optional abstraction provided for your convenience when creating React elements and it won't run in ES5 browsers without first being transformed by Babel. 46 | 47 | ## Transforming JSX via Babel in the Browser 48 | 49 | Normally, Babel is setup to automatically process your JavaScript files during development using the Babel CLI tool (e.g., via something like [webpack](https://webpack.github.io/)). However, it is possible to use Babel directly in the browser by way of a script include. As we are just getting started we'll avoid CLI tools or learning a module loader to focus on learning React. Note that you should never use this browser transformation in a production environment. 50 | 51 | The Babel project unfortunately, as of Babel 6, no longer provides the script file needed (i.e., `browser.js`) to transform JSX code to ES5 code in the browser. Thus you will have to use an older version of Babel (i.e., 5.8.23) that provides the needed file (i.e., `browser.js`) for transforming JSX/ES* in the browser. 52 | 53 | ### Using `browser.js` (Babel 5.8.23) to Transform JSX in the Browser 54 | 55 | In the HTML file below the React code we have been working with to create the `HelloMessage` component has been updated to use JSX. The transformation of the code is occurring because we have included the `browser.js` Babel file and given the ` 62 | 63 | 64 | 65 | 66 |
67 | 76 | 77 | 78 | ``` 79 | 80 | While transforming JSX in the browser is convenient and easy to setup, it isn't ideal because the transformation cost is occurring at runtime. This will slow down your web pages and may cause memory issues. Therefore using browser.js is ***not a production solution***. 81 | 82 | You should be aware that the code examples used in this book via JSFiddle will be using the `browser.js` (Babel 5.8.23) to transform JSX into ES5 code. In other words, JSFiddle is pretty much doing what you see in the HTML file above when running React code. 83 | 84 | #### Notes 85 | 86 | * The Babel tool is a [subjective selection](https://facebook.github.io/react/blog/2015/09/10/react-v0.14-rc1.html#compiler-optimizations) from the React team for transforming ES* code and JSX syntax to ES5 code. Learn more about Babel by reading the [Babel handbook](https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/user-handbook.md). 87 | * By using JSX: 88 | * Less technical people can still understand and modify the required parts. CSS developers and designers will find JSX more familiar than JavaScript alone. 89 | * You can leverage the full power of JavaScript in HTML and avoid learning or using a templating language. JSX is not a templating solution. It is a declarative syntax used to express a tree structure of UI components. 90 | * The compiler will find errors in your HTML you might otherwise miss. 91 | * JSX promotes the idea of inline styles. Which can be a good thing. 92 | * Beware of JSX [Gotchas](http://facebook.github.io/react/docs/jsx-gotchas.html). 93 | * A [JSX specification is currently being drafted](https://facebook.github.io/jsx/). It can be used by anyone as an a XML-like syntax extension to ECMAScript without any defined semantics. 94 | -------------------------------------------------------------------------------- /react-basic-setup/3.3.md: -------------------------------------------------------------------------------- 1 | ## Using ES6 & ES\* With React 2 | 3 | Babel is not part of React. In fact, Babel's purpose isn't even that of a JSX transformer. Babel is a JavaScript compiler first. It takes ES\* code and transforms it to run in browsers that don't support ES\* code. As of today, Babel mostly takes ES6 and ES7 code and transforms it into ES5 code. When doing these ECMAScript transformations it is trivial to also transform JSX expressions into `React.createElement()` calls. This is what we examined in the previous section. 4 | 5 | Given that Babel is the mechanism for transforming JSX, it allows you to write code that will run in future versions of ES\*. 6 | 7 | In the HTML page below the familiar `HelloMessage` component has been rewritten to [take advantage](http://babeljs.io/blog/2015/06/07/react-on-es6-plus/) of [ES6 classes](https://github.com/lukehoban/es6features#classes). Not only is Babel transforming the JSX syntax, it is also transforming ES6 class syntax to ES5 syntax which can then be parsed by ES5 browser engines. 8 | 9 | ```html 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 39 | 40 | 41 | ``` 42 | 43 | In the above HTML document Babel is taking in: 44 | 45 | ```javascript 46 | class HelloMessage extends React.Component { 47 | render(){ 48 | return
Hello {this.props.name}
; 49 | } 50 | }; 51 | 52 | ReactDOM.render(, document.getElementById('app')); 53 | ``` 54 | 55 | And transforming it to this: 56 | 57 | ```javascript 58 | "use strict"; 59 | 60 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 61 | 62 | var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 63 | 64 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 65 | 66 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 67 | 68 | var HelloMessage = (function (_React$Component) { 69 | _inherits(HelloMessage, _React$Component); 70 | 71 | function HelloMessage() { 72 | _classCallCheck(this, HelloMessage); 73 | 74 | _get(Object.getPrototypeOf(HelloMessage.prototype), "constructor", this).apply(this, arguments); 75 | } 76 | 77 | _createClass(HelloMessage, [{ 78 | key: "render", 79 | value: function render() { 80 | return React.createElement( 81 | "div", 82 | null, 83 | "Hello ", 84 | this.props.name 85 | ); 86 | } 87 | }]); 88 | 89 | return HelloMessage; 90 | })(React.Component); 91 | 92 | ; 93 | 94 | ReactDOM.render(React.createElement(HelloMessage, { name: "John" }), document.getElementById('app')); 95 | ``` 96 | 97 | Most [ES6 features](https://github.com/lukehoban/es6features) with a few caveats can be used when writing JavaScript that is transformed by Babel 5.8.23 (i.e., [https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.js](https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.js)). 98 | 99 | #### Notes 100 | 101 | * Obviously one can could still use Babel for it's intended purpose (i.e., compiling newer JavaScript code to older JavaScript code) without using JSX. However, most people using React are taking advantage of Babel for both unsupported ES\* features and JSX transforming. 102 | * Learn more about Babel by reading the [Babel handbook](https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/user-handbook.md). 103 | -------------------------------------------------------------------------------- /react-basic-setup/3.4.md: -------------------------------------------------------------------------------- 1 | ## Writing React With JSFiddle 2 | 3 | The basic setup that has been described in this chapter can be used online via JSfiddle. JSFiddle uses the same three resources used earlier to make writing React online simple. 4 | 5 | * `react-with-addons.js` (the newer version of `react.js`) 6 | * `react-dom.js` 7 | * `browser.js` 8 | 9 | Below is an embedded JSFiddle containing the `HelloMessage` component used throughout this chapter. By clicking on the "results" tab you can view the React component rendered to the DOM. To edit the code just click on "edit with JSFiddle". 10 | 11 | > [source code](https://jsfiddle.net/bvpe4j39/) 12 | 13 | Note that the "Babel" tab indicates the JavaScript written into this tab will be transformed by Babel (similar too, if not directly using `browser.js`). The "Resources" tab shows that JSFiddle is pulling in the `react.js` and `react-dom.js` files. 14 | 15 | It will be assumed that after reading this chapter that you understand the basic requirements to setup React and Babel via `browser.js`. And that while JSFiddle does not make it obvious, this is the same exact setup being used by JSFiddle to run React code. 16 | 17 | JSFiddle will be used throughout the rest of this book to show the results of React code transformed by Babel. 18 | -------------------------------------------------------------------------------- /react-jsx.md: -------------------------------------------------------------------------------- 1 | # JavaScript Syntax Extension (a.k.a, JSX) 2 | 3 | In the previous chapter we learned how to create React nodes using plain ES5 JavaScript code. In this chapter we look at creating React nodes using the JSX syntax extension. 4 | 5 | After this Chapter JSX will be used for the remainder of this book unless invoking a `React.createElement()` function is required for the sake of clarity. 6 | -------------------------------------------------------------------------------- /react-jsx/5.1.md: -------------------------------------------------------------------------------- 1 | # What Is JSX? 2 | 3 | JSX is an XML/HTML-like syntax used by React that extends ECMAScript so that XML/HTML-like text can co-exist with JavaScript/React code. The syntax is intended to be used by preprocessors (i.e., transpilers like Babel) to transform HTML-like text found in JavaScript files into standard JavaScript objects that a JavaScript engine will parse. 4 | 5 | Basically, by using JSX you can write concise HTML/XML-like structures (e.g., DOM like tree structures) in the same file as you write JavaScript code, then Babel will transform these expressions into actual JavaScript code. Unlike the past, instead of putting JavaScript into HTML, JSX allows us to put HTML into JavaScript. 6 | 7 | By using JSX one can write the following JSX/JavaScript code: 8 | 9 | ```js 10 | var nav = ( 11 | 17 | ); 18 | ``` 19 | 20 | And Babel will transform it into this: 21 | 22 | ```js 23 | var nav = React.createElement( 24 | "ul", 25 | { id: "nav" }, 26 | React.createElement( 27 | "li", 28 | null, 29 | React.createElement( 30 | "a", 31 | { href: "#" }, 32 | "Home" 33 | ) 34 | ), 35 | React.createElement( 36 | "li", 37 | null, 38 | React.createElement( 39 | "a", 40 | { href: "#" }, 41 | "About" 42 | ) 43 | ), 44 | React.createElement( 45 | "li", 46 | null, 47 | React.createElement( 48 | "a", 49 | { href: "#" }, 50 | "Clients" 51 | ) 52 | ), 53 | React.createElement( 54 | "li", 55 | null, 56 | React.createElement( 57 | "a", 58 | { href: "#" }, 59 | "Contact Us" 60 | ) 61 | ) 62 | ); 63 | ``` 64 | 65 | You can think of JSX as a shorthand for calling `React.createElement()`. 66 | 67 | The idea of mixing HTML and JavaScript in the same file can be a rather contentious topic. Ignore the debate. Use it if you find it helpful. If not, write the React code required to create React nodes. Your choice. My opinion is that JSX provides a concise and familiar syntax for defining a tree structure with attributes that does not require learning a templating language or leaving JavaScript. Both of which can be a win when building large applications. 68 | 69 | It should be obvious but JSX is easier to read and write over large pyramids of JavaScript function calls or object literals (e.g., contrast the two code samples in this section). Additionally the React team clearly believes JSX is better suited for defining UI's than a traditional templating (e.g., Handlebars) solution: 70 | 71 | > markup and the code that generates it are intimately tied together. Additionally, display logic is often very complex and using template languages to express it becomes cumbersome. We've found that the best solution for this problem is to generate HTML and component trees directly from the JavaScript code such that you can use all of the expressive power of a real programming language to build UIs. 72 | > 73 | 74 | #### Notes 75 | 76 | * Don't think of JSX as a template but instead as a special/alternative JS syntax that has to be compiled. I.e., JSX is simply converting XML-like markup into JavaScript. 77 | * The Babel tool is a [subjective selection](https://facebook.github.io/react/blog/2015/09/10/react-v0.14-rc1.html#compiler-optimizations) from the React team for transforming ES* code and JSX syntax to ES5 code. You can learn more about Babel at [http://babeljs.io/](http://babeljs.io/) or by reading the [Babel handbook](https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/user-handbook.md). 78 | * The merits of JSX in four bullet points: 79 | * Less technical people can still understand and modify the required parts. CSS developers and designers will find JSX more familiar than JavaScript alone. I.e., HTML markup, using JSX, looks like HTML markup instead of a pyramid of `createElement()` function. 80 | * You can leverage the full power of JavaScript in HTML and avoid learning or using a templating language. JSX is not a templating solution. It is a declarative syntax used to express a tree structure of UI nodes and components. 81 | * By adding a JSX transformation step you'll find errors in your HTML you might otherwise miss. 82 | * JSX promotes the idea of inline styles. Which can be a good thing. 83 | * Beware of JSX [Gotchas](http://facebook.github.io/react/docs/jsx-gotchas.html). 84 | * JSX is a separate thing from React itself. JSX does not attempt to comply with any XML or HTML specifications. JSX is designed as an ECMAScript feature and the similarity to XML/HTML is only at the surface (i.e., it looks like XML/HTML so you can just write something familiar). A [JSX specification is currently being drafted](https://facebook.github.io/jsx/) to by used by anyone as an a XML-like syntax extension to ECMAScript without any defined semantics. 85 | * In JSX, `` alone is valid while `` alone isn't. You have to close all tags, always. 86 | -------------------------------------------------------------------------------- /react-jsx/5.2.md: -------------------------------------------------------------------------------- 1 | # Creating React Nodes With JSX 2 | 3 | Working off the knowledge given in the previous chapter you should be familiar with creating React nodes using the `React.createElement()` function. For example, using this function one can create React nodes which both represent HTML DOM nodes and custom HTML DOM nodes. Below I use this familiar function to create two React nodes. 4 | 5 | ```js 6 | //React node, which represents an actual HTML DOM node 7 | var HTMLLi = React.createElement('li', {className:'bar'}, 'foo'); 8 | 9 | //React node, which represents a custom HTML DOM node 10 | var HTMLCustom = React.createElement('foo-bar', {className:'bar'}, 'foo'); 11 | ``` 12 | 13 | To use JSX instead (assuming you have Babel setup) of `React.createElement()` to create these React nodes one just has to replace `React.createElement()` function calls with the HTML/XML like tags which represent the HTML you'd like the virtual DOM to spit out. The above code can be written in JSX like so. 14 | 15 | ```js 16 | //React node, which represents an actual HTML DOM node 17 | var HTMLLi =
  • foo
  • ; 18 | 19 | //React node, which represents a custom HTML DOM node 20 | var HTMLCustom = foo; 21 | ``` 22 | 23 | Notice that the JSX is not in a JavaScript string format and can just be writing as if you are writing it inside of an `.html` file. As stated many times already JSX is then transformed back into the `React.createElement()` functions calls by Babel. You can see the transformation occurring in the following JSFiddle (i.e., Babel is transforming JSX to JavaScript, then React is creating DOM nodes). 24 | 25 | > [source code](https://jsfiddle.net/wc6dtkov/#tabs=js,result,html,resources) 26 | 27 | If you were to examine the actual HTML produced in the above JSfiddle it would look like so: 28 | 29 | ```html 30 | 31 |
  • foo
  • 32 |
    foo
    33 | 34 | ``` 35 | 36 | Creating React nodes using JSX is as simple as writing HTML like code in your JavaScript files. 37 | 38 | #### Notes 39 | 40 | * JSX tags support the XML self close syntax so you can optionally leave the closing tag off when no child node is used. 41 | * If you pass props/attributes to native HTML elements that do not exist in the HTML specification, React will not render them to the actual DOM. However, if you use a custom element (i.e., not a stand HTML element) then arbitrary/custom attributes will be added to custom elements (e.g., ``). 42 | * The `class` attribute has to be written `className` 43 | * The `for` attribute has to be written `htmlFor` 44 | * The `style` attribute takes an object of [camel-cased style properties](https://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSS2Properties) 45 | * All attributes are camel-cased (e.g., `accept-charset` is written as `acceptCharset`) 46 | * To represent HTML elements, ensure the HTML tag is lower-cased 47 | * The following are the HTML attributes that React supports (shown in camel-case): 48 | 49 | ```HTML 50 | accept acceptCharset accessKey action allowFullScreen allowTransparency alt 51 | async autoComplete autoFocus autoPlay capture cellPadding cellSpacing challenge 52 | charSet checked classID className colSpan cols content contentEditable 53 | contextMenu controls coords crossOrigin data dateTime default defer dir 54 | disabled download draggable encType form formAction formEncType formMethod 55 | formNoValidate formTarget frameBorder headers height hidden high href hrefLang 56 | htmlFor httpEquiv icon id inputMode integrity is keyParams keyType kind label 57 | lang list loop low manifest marginHeight marginWidth max maxLength media 58 | mediaGroup method min minLength multiple muted name noValidate nonce open 59 | optimum pattern placeholder poster preload radioGroup readOnly rel required 60 | reversed role rowSpan rows sandbox scope scoped scrolling seamless selected 61 | shape size sizes span spellCheck src srcDoc srcLang srcSet start step style 62 | summary tabIndex target title type useMap value width wmode wrap 63 | ``` 64 | -------------------------------------------------------------------------------- /react-jsx/5.3.md: -------------------------------------------------------------------------------- 1 | # Rendering JSX to DOM 2 | 3 | The `ReactDOM.render()` function can be used to render JSX expressions to the DOM. Actually, after Babel transforms the JSX all it is doing is rendering nodes created by `React.createElement()`. Again, JSX is just a stand in expression for having to write out the `React.createElement()` function calls. 4 | 5 | In the code example I am rendering a `
  • ` element and a custom `` element to the DOM using JSX expressions. 6 | 7 | > [source code](https://jsfiddle.net/e1thfjro/#tabs=js,result,html,resources) 8 | 9 | Once rendered to the DOM, the HTML will look like so: 10 | 11 | ```html 12 | 13 |
  • foo
  • 14 |
    foo
    15 | 16 | ``` 17 | 18 | Just remember that Babel is taking the JSX in your JavaScript files transforming it to React nodes (i.e., `React.createElement()` functions calls) then using these nodes created by React (i.e., the Virtual DOM) as a template for creating a real html DOM branch. The part where the React nodes are turned into the real DOM nodes and added to the DOM in an HTML page occurs when `ReactDOM.render()` is called. 19 | 20 | #### Notes 21 | 22 | * Any DOM nodes inside of the DOM element in which you are rendering will be removed/replaced. 23 | * `ReactDOM.render()` does not modify the DOM element node in which you are rendering React. 24 | * Rendering to an HTML DOM is only one option with React, [other rendering APi's are available](https://facebook.github.io/react/docs/top-level-api.html#reactdomserver.rendertostring). For example, it is also possible to render to a string (i.e., `ReactDOMServer.renderToString()`) on the server-side. 25 | * Re-rendering to the same DOM element will only update the current child nodes if a change (i.e., diff) has occurred or a new child node have been added. 26 | * Don’t ever call `this.render()` yourself, leave that to React 27 | -------------------------------------------------------------------------------- /react-jsx/5.4.md: -------------------------------------------------------------------------------- 1 | # Using JavaScript Expressions in JSX 2 | 3 | Hopefully by now it's obvious that JSX is just syntactical sugar that gets converted to real JavaScript. But what happens when you want to intermingle real JavaScript code within JSX? To write a JavaScript expression within JSX you will have to surround the JavaScript code in `{ }` brackets. 4 | 5 | In the React/JSX code below I am mixing JavaScript expressions (e.g., `2+2`), surround by `{ }` among the JSX that will eventually get evaluated by JavaScript. 6 | 7 | > [source code](https://jsfiddle.net/9x24jp95/#tabs=js,result,html,resources) 8 | 9 | The JSX transformation will result in the follow: 10 | 11 | ```js 12 | var label = '2 + 2'; 13 | var inputType = 'input'; 14 | 15 | var reactNode = React.createElement( 16 | 'label', 17 | null, 18 | label, 19 | ' = ', 20 | React.createElement('input', { type: inputType, value: 2 + 2 }) 21 | ); 22 | 23 | ReactDOM.render(reactNode, document.getElementById('app1')); 24 | ``` 25 | 26 | Once this code is parsed by a JavaScript engine (i.e., a browser) the JavaScript expressions are evaluated and the resulting HTML will look like so: 27 | 28 | ```html 29 |
    30 | 31 |
    32 | ``` 33 | 34 | Nothing that complicated is going on here once you realize that the brackets basically escape the JSX. The `{ }` brackets simply tells JSX that the content is JavaScript so leave it alone so it can eventually be parsed by a JavaScript engine (e.g., `2+2`). Note that `{ }` brackets can be used anywhere among the JSX expressions as long as the result is valid JavaScript. 35 | 36 | #### Notes 37 | 38 | * If you have to escape brackets (i.e., you want brackets in a string) use `{'{}'}`. 39 | -------------------------------------------------------------------------------- /react-jsx/5.5.md: -------------------------------------------------------------------------------- 1 | # Using JavaScript Comments in JSX 2 | 3 | You can place JavaScript comments anywhere in React/JSX you want except locations where JSX might expect a React child node. In this situation you'll have to escape the comment using `{ }` so that JSX knows to pass that on as actual JavaScript. 4 | 5 | Examine the code below, make sure you understand where you'll have to tell JSX to pass along a JS comment so a child React node is not created. 6 | 7 | ```js 8 | var reactNode =
    {/* use {'{}'} here to comment*/}
    ; 9 | ``` 10 | 11 | In the above code if I had not wrapped the comment inside of the `
    ` with `{ }` brackets then Babel would have converted the comment to a React text node. The outcome, unintentionally, without the `{ }` would be: 12 | 13 | ```js 14 | var reactNode = React.createElement( 15 | "div", 16 | null, 17 | "/* use ", 18 | "{}", 19 | " here to comment*/" 20 | ); 21 | ``` 22 | 23 | Which would result in the following HTML that would have unintended text nodes. 24 | 25 | ```html 26 |
    27 | /* use 28 | {} 29 | here to comment*/ 30 |
    31 | ``` 32 | -------------------------------------------------------------------------------- /react-jsx/5.6.md: -------------------------------------------------------------------------------- 1 | # Using Inline CSS in JSX 2 | 3 | In order to define inline styles on React nodes you need to pass the `style` prop/attribute a JavaScript object or reference to an object containing CSS properties and values. 4 | 5 | In the code below I first setup a JavaScript object, named `styles`, containing inline styles. Then I use the `{ }` brackets to reference the object that should be used for the value of the style prop/attribute (e.g., `style={styles}`). 6 | 7 | > [source code](https://jsfiddle.net/4pw9w9h7/#tabs=js,result,html,resources) 8 | 9 | Notice that, the CSS properties are in a camelCased form similar to what is used when writing [CSS properties in JavaScript](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference). This is required because JavaScript does not allow hyphens in names. 10 | 11 | When the above React/JSX code is transformed by Babel, and then parsed by a JavaScript engine, the resulting HTML will be: 12 | 13 | ```html 14 |
    test
    15 | ``` 16 | 17 | #### Notes 18 | 19 | * Vendor prefixes other than ms should begin with a capital letter. This is why WebkitTransition has an uppercase "W". 20 | * CamelCased CSS properties shouldn't be a suprise given this is how it is done when accessing properties on DOM nodes from JS (e.g., `document.body.style.backgroundImage`) 21 | * When specifying a pixel value React will automatically append the string "px" for you after your number value except for the following properties: 22 | 23 | ```html 24 | columnCount fillOpacity flex flexGrow flexShrink fontWeight lineClamp lineHeight 25 | opacity order orphans strokeOpacity widows zIndex zoom 26 | ``` 27 | -------------------------------------------------------------------------------- /react-jsx/5.7.md: -------------------------------------------------------------------------------- 1 | # Defining Attributes/Props in JSX 2 | 3 | In the previous chapter, section 4.4, I discussed passing `React.createElement(type, props, children)` attributes/props when defining React nodes. Since JSX is transformed into `React.createElement()` function calls you basically already have a understanding of how React node attributes/props work. However, since JSX is used to express XML-like nodes that get turned into HTML, attribute/props are defined by adding the attributes/props to JSX expressions as name-value attributes. 4 | 5 | In the code example below I am defining a React `
  • ` element node, using JSX, with five attributes/props. One is a non-standard HTML attribute (e.g., `foo:'bar'`) and the others are known HTML attributes. 6 | 7 | ```js 8 | var styles = {backgroundColor:'red'}; 9 | var tested = true; 10 | var text = 'text'; 11 | 12 | var reactNodeLi =
  • 18 | {text} 19 |
  • ; 20 | 21 | ReactDOM.render(reactNodeLi, document.getElementById('app1')); 22 | ``` 23 | The JSX when it is transformed will look like this (note that attributes/props just become arguments to a function): 24 | 25 | ``` 26 | var reactNodeLi = React.createElement( 27 | 'li', 28 | { id: '', 29 | 'data-test': tested ? 'test' : 'false', 30 | className: 'blue', 31 | 'aria-test': 'test', 32 | style: styles, 33 | foo: 'bar' }, 34 | text 35 | ); 36 | ``` 37 | When the `reactNodeLi` node is render to the DOM it will look like this: 38 | 39 | ```HTML 40 |
    41 |
  • 47 | text 48 |
  • 49 |
    50 | ``` 51 | 52 | You should note the following: 53 | 54 | 1. Leaving an attribute/prop blank results in that attribute value becoming true (e.g., `id=""` becomes `id="true"` and `test` becomes `test="true"`) 55 | 2. The `foo` attribute, because it was not a standard HTML attribute, doesn't become a final HTML attribute. 56 | 57 | #### Notes 58 | 59 | * If an attribute/prop is duplicated the last one defined wins. 60 | * If you pass props/attributes to native HTML elements that do not exist in the HTML specification, React will not render them. However, if you use a custom element (i.e., not a standard HTML element) then arbitrary/custom attributes will be added to custom elements (e.g., ``). 61 | * Omitting the value of an attribute/prop causes JSX to treat it as true (i.e., `` becomes ``). This will even occur for attributes/props that are not presented in the final HTML due to the fact they are not actual HTML attributes. 62 | * The `class` attribute has to be written `className` 63 | * The `for` attribute has to be written `htmlFor` 64 | * The `style` attribute takes a reference to an object of [camel-cased style properties](https://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSS2Properties) 65 | * HTML form elements (e.g., ``, ``, etc.) created [as React nodes](https://facebook.github.io/react/docs/forms.html) support a few attributes/props that are affected by user interaction. These are: `value`, `checked`, and `selected`. 66 | * React offers the [`key`](https://facebook.github.io/react/docs/multiple-components.html#dynamic-children), [`ref`](https://facebook.github.io/react/docs/more-about-refs.html), and [`dangerouslySetInnerHTML`](https://facebook.github.io/react/tips/dangerously-set-inner-html.html) attributes/props that don't exist in DOM and take on a unique role/function. 67 | * All attributes are camel-cased (e.g., `accept-charset` is written as `acceptCharset`) which differs from how they are written in HTML. 68 | * The following are the HTML attributes that React supports (shown in camel-case): 69 | 70 | ```HTML 71 | accept acceptCharset accessKey action allowFullScreen allowTransparency alt 72 | async autoComplete autoFocus autoPlay capture cellPadding cellSpacing challenge 73 | charSet checked classID className colSpan cols content contentEditable 74 | contextMenu controls coords crossOrigin data dateTime default defer dir 75 | disabled download draggable encType form formAction formEncType formMethod 76 | formNoValidate formTarget frameBorder headers height hidden high href hrefLang 77 | htmlFor httpEquiv icon id inputMode integrity is keyParams keyType kind label 78 | lang list loop low manifest marginHeight marginWidth max maxLength media 79 | mediaGroup method min minLength multiple muted name noValidate nonce open 80 | optimum pattern placeholder poster preload radioGroup readOnly rel required 81 | reversed role rowSpan rows sandbox scope scoped scrolling seamless selected 82 | shape size sizes span spellCheck src srcDoc srcLang srcSet start step style 83 | summary tabIndex target title type useMap value width wmode wrap 84 | ``` 85 | -------------------------------------------------------------------------------- /react-jsx/5.8.md: -------------------------------------------------------------------------------- 1 | # Defining Events in JSX 2 | 3 | In the previous chapter, in section 4.7, it was explained and demonstrated how events are defined on React nodes. To do the same thing in JSX you add the same camelCased event and the corresponding handler/callback as a prop/attribute of the JSX representing the React node. 4 | 5 | Below is the none JSX way of adding an event to a React node (example from Previous chapter, section 4.7): 6 | 7 | > [source code](https://jsfiddle.net/ct5acw2y/#tabs=js,result,html,resources) 8 | 9 | The above code written using JSX: 10 | 11 | > [source code](https://jsfiddle.net/tvmqwuu1/#tabs=js,result,html,resources) 12 | 13 | Note that we are using the `{ }` brackets to connect a JS function to an event (i.e., `onMouseOver={mouseOverHandler}`). This style of adding events to nodes mimics the [DOM 0 style of inlining events on HTML elements](http://stackoverflow.com/questions/5642659/what-is-the-difference-between-dom-level-0-events-vs-dom-level-2-events) (Don't worry, just mimics, does not really create inline events in the DOM). 14 | 15 | React supports the following events and event specific syntheticEvent properties: 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 64 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 98 | 99 | 100 | 101 | 102 | 106 | 107 | 108 | 109 | 110 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 138 | 139 | 140 | 141 | 142 | 143 | 148 | 149 | 150 |
    Event Type/Category:Events:Event Specific Properties:

    Clipboard

    onCopy, onCut, onPasteDOMDataTransfer, clipboardData

    Composition

    onCompositionEnd, onCompositionStart, onCompositionUpdatedata

    Keyboard

    onKeyDown, onKeyPress, onKeyUpaltKey, 37 | charCode, 38 | ctrlKey, 39 | getModifierState(key), 40 | key, 41 | keyCode, 42 | locale, 43 | location, 44 | metaKey, 45 | repeat, 46 | shiftKey, 47 | which

    Focus

    onChange, onInput, onSubmitDOMEventTarget, relatedTarget

    Form

    onFocus, onBlur

    Mouse

    onClick, onContextMenu, onDoubleClick, onDrag, onDragEnd, onDragEnter, onDragExit 62 | onDragLeave, onDragOver, onDragStart, onDrop, onMouseDown, onMouseEnter, onMouseLeave 63 | onMouseMove, onMouseOut, onMouseOver, onMouseUpaltKey, 65 | button, 66 | buttons, 67 | clientX, 68 | clientY, 69 | ctrlKey, 70 | getModifierState(key), 71 | metaKey, 72 | pageX, 73 | pageY, 74 | DOMEventTarget relatedTarget, 75 | screenX, 76 | screenY, 77 | shiftKey, 78 |

    Selection

    onSelect

    Touch

    onTouchCancel, onTouchEnd, onTouchMove, onTouchStart 89 | altKey 90 | DOMTouchList changedTouches, 91 | ctrlKey, 92 | getModifierState(key), 93 | metaKey, 94 | shiftKey, 95 | DOMTouchList targetTouches, 96 | DOMTouchList touches, 97 |

    UI

    onScroll 103 | detail, 104 | DOMAbstractView view 105 |

    Wheel

    onWheel 111 | deltaMode, 112 | deltaX, 113 | deltaY, 114 | deltaZ, 115 |

    Media

    onAbort, onCanPlay, onCanPlayThrough, onDurationChange, onEmptied, onEncrypted, onEnded, onError, onLoadedData, onLoadedMetadata, onLoadStart, onPause, onPlay, onPlaying, onProgress, onRateChange, onSeeked, onSeeking, onStalled, onSuspend, onTimeUpdate, onVolumeChange, onWaiting

    Image

    onLoad, onError

    Animation

    onAnimationStart, onAnimationEnd, onAnimationIteration 134 | animationName, 135 | pseudoElement, 136 | elapsedTime 137 |

    Transition

    onTransitionEnd 144 | propertyName, 145 | pseudoElement, 146 | elapsedTime 147 |
    151 | 152 | 153 | 154 | #### Notes 155 | 156 | * React normalizes events so that they behave consistently across different browsers. 157 | * Events in React are triggered on the bubbling phase. To trigger an event on the capturing phase add the word "Capture" to the event name (e.g., `onClick` would become `onClickCapture`). 158 | * If you need the browser event details for a given event you can access this by using the `nativeEvent` property found in the SyntheticEvent object passed into React event hander/callbacks. 159 | * React does not actually attach events to the nodes themselves, it uses [event delegation](http://domenlightenment.com/#11.14). 160 | * `e.stopPropagation()` or `e.preventDefault()` should be triggered manually to [stop](http://domenlightenment.com/#11.9) event [propagation](http://domenlightenment.com/#11.10) instead of `returning false;`. 161 | * Not all DOM events are provided by React. But you can still make use of them [using React lifecycle methods](https://facebook.github.io/react/tips/dom-event-listeners.html). 162 | -------------------------------------------------------------------------------- /react-nodes.md: -------------------------------------------------------------------------------- 1 | # React Nodes 2 | 3 | This section will discuss creating React nodes ([text](http://domenlightenment.com/#7) or [element](http://domenlightenment.com/#3) nodes) using JavaScript. 4 | -------------------------------------------------------------------------------- /react-nodes/4.1.md: -------------------------------------------------------------------------------- 1 | # What Is a React Node? 2 | 3 | The primary type or value that is created when using React is known as a React node. A React node is defined as: 4 | 5 | > a light, stateless, immutable, virtual representation of a DOM node. 6 | 7 | React nodes are not [real DOM nodes](http://domenlightenment.com/#1) (e.g., [text](http://domenlightenment.com/#7) or [element](http://domenlightenment.com/#3) nodes) themselves, but a representation of a potential DOM node. The representation is considered the virtual DOM. In a nutshell, React is used to define a virtual DOM using React nodes, that fuel React components, that can eventually be used to create a real DOM structured or other structures (e.g., [React Native](https://facebook.github.io/react-native/)). 8 | 9 | React nodes can be created using JSX or JavaScript. In this chapter we'll look at creating React nodes using JavaScript alone. No JSX yet. I believe that you should first learn what JSX is concealing in order to understand JSX. 10 | 11 | You might be tempted to skip this chapter because you already know that you will be using JSX. I'd suggest reading this chapter so you are aware of what JSX is doing for you. This is likely the most important chapter in the book to [Grok](https://en.wikipedia.org/wiki/Grok). 12 | -------------------------------------------------------------------------------- /react-nodes/4.2.md: -------------------------------------------------------------------------------- 1 | # Creating React Nodes 2 | 3 | In most cases developers using React will favor JSX and use it to create React nodes. Despite this, in this chapter we are going to examine how React nodes can be created without JSX, using only JavaScript. The next chapter will discuss creating React nodes using JSX. 4 | 5 | Creating React nodes using JavaScript is as simple as calling the `React.createElement(type,props,children)` function and passing it a set of arguments defining an actual DOM node (e.g., type = an html element e.g., `
  • ` or custom element e.g., ``). 6 | 7 | The `React.createElement()` arguments are explained below: 8 | 9 | * type (string | `React.createClass()`): 10 | 11 | Can be a string which represents an HTML element (or custom HTML element) or React component instance (i.e., an instance of `React.createClass()`) 12 | 13 | * props (null | object): 14 | 15 | Can be `null` or an object containing attributes/props and values 16 | 17 | * children (null | string | `React.createClass()` | `React.createElement()`): 18 | 19 | Children can be `null`, a string that gets turned into a text node, an instance of `React.createClass()` or `React.createElement()` 20 | 21 | Below I use the `React.createElement()` function to create a virtual DOM representation of a `
  • ` element node containing a text node of `one` (a.k.a., React text) and an `id` of `li1`. 22 | 23 | ```js 24 | var reactNodeLi = React.createElement('li', {id:'li1'}, 'one'); 25 | ``` 26 | 27 | Notice that the first argument defines the HTML element I want to represent. The second argument defines the attributes/props on the `
  • `. And the third argument defines what the node inside of the element will be. In this case, I am simply placing a child text node (i.e., `'one'`) inside the `
  • `. The last argument that becomes a child of the node being created can be 28 | 29 | * A React text node 30 | * A React element node, or 31 | * A React component instance. 32 | 33 | At this point all I've done is create a React element node containing a React text node that I have stored into the variable `reactNodeLi`. To create a virtual DOM we have to actually render the React element node to a real DOM. To do this we use the `ReactDOM.render()` function. 34 | 35 | ```js 36 | ReactDOM.render(reactNodeLi, document.getElementById('app')); 37 | ``` 38 | 39 | The above code, loosely stated, invokes the following: 40 | 41 | 1. Create a virtual DOM constructed from the React element node passed in (`reactNodeLi`) 42 | 2. Use the virtual DOM to re-construct a real DOM branch 43 | 3. Insert the real DOM branch (i.e., `
  • one
  • `) into the DOM as a child node of `
    `. 44 | 45 | In other words, the HTML DOM changes from this: 46 | 47 | ```html 48 |
    49 | ``` 50 | 51 | to this: 52 | 53 | ```html 54 |
    55 | //note that React added the react data-reactid attribute 56 |
  • one
  • 57 |
    58 | ``` 59 | 60 | This was a rather simplistic example. Using `React.createElement()` a complex structure can be created as well. For example, below I'm using `React.createElement()` to create a bunch of React nodes representing an HTML unordered list of text words (i.e., `
      `). 61 | 62 | ```js 63 | // Create React element
    • 's 64 | var rElmLi1 = React.createElement('li', {id:'li1'}, 'one'), 65 | rElmLi2 = React.createElement('li', {id:'li2'}, 'two'), 66 | rElmLi3 = React.createElement('li', {id:'li3'}, 'three'); 67 | 68 | // Create
        React element and add child 69 | // React
      • elements to it 70 | var reactElementUl = React.createElement('ul', {className:'myList'}, rElmLi1, rElmLi2, rElmLi3); 71 | ``` 72 | 73 | Before rendering the unordered list to the DOM I think it is worth showing that the above code can be simplified by using the `React.createElement()` in place of variables. This also demonstrates how a hierarchy or DOM branch can be defined using JavaScript. 74 | 75 | ```js 76 | var reactElementUl = React.createElement( 77 | 'ul', { 78 | className: 'myList' 79 | }, 80 | React.createElement('li', {id: 'li1'}, 'one'), 81 | React.createElement('li', {id: 'li2'}, 'two'), 82 | React.createElement('li', {id: 'li3'}, 'three') 83 | ); 84 | ``` 85 | 86 | When the above code is rendered to the DOM the resulting HTML will look like: 87 | 88 | ```html 89 |
          90 |
        • one
        • 91 |
        • two
        • 92 |
        • three
        • 93 |
        94 | ``` 95 | 96 | You can investigate this yourself using the JSFiddle below: 97 | 98 | > [source code](https://jsfiddle.net/bLy9Lu47/#tabs=js,result,html,resources) 99 | 100 | It should be obvious that React nodes are just JavaScript objects in a tree that represent real DOM nodes inside of a virtual DOM tree. The virtual DOM is then used to construct an actual DOM branch in an HTML page. 101 | 102 | #### Notes 103 | 104 | * The `type` argument passed to `React.createElement(type, props, children)` can be 105 | * A string indicating a standard HTML element (e.g., `'li'` = `
      • `), or 106 | * A custom element (e.g., `'foo-bar'` = ``, or a React component instance (i.e., an instance of `React.createClass()`. 107 | * These are the standard HTML elements that React supports (i.e. these elements passed as a string `type` to `createElement()`). They create the associating standard HTML element in the DOM): 108 | 109 | ```html 110 | a abbr address area article aside audio b base bdi bdo big blockquote body br 111 | button canvas caption cite code col colgroup data datalist dd del details dfn 112 | dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 113 | h6 head header hgroup hr html i iframe img input ins kbd keygen label legend li 114 | link main map mark menu menuitem meta meter nav noscript object ol optgroup 115 | option output p param picture pre progress q rp rt ruby s samp script section 116 | select small source span strong style sub summary sup table tbody td textarea 117 | tfoot th thead time title tr track u ul var video wbr 118 | ``` 119 | -------------------------------------------------------------------------------- /react-nodes/4.3.md: -------------------------------------------------------------------------------- 1 | # Rendering to DOM 2 | 3 | React provides the `ReactDOM.render()` function from [`react-dom.js`](https://github.com/facebook/react/blob/master/src/renderers/dom/ReactDOM.js) that can be used to render React nodes to the DOM. We've already seen this `render()` function in use in this chapter. 4 | 5 | In the code example below, using `ReactDOM.render()`, the `'
      • '` and `''` React nodes are rendered to the DOM. 6 | 7 | > [source code](https://jsfiddle.net/LLz4p3ox/#tabs=js,result,html,resources) 8 | 9 | Once rendered to the DOM, the updated HTML will be: 10 | 11 | ```html 12 | 13 |
      • foo
    14 |
    foo
    15 | 16 | ``` 17 | 18 | The `ReactDOM.render()` function is initially how you get the React nodes to the Virtual DOM, then to the HTML DOM. 19 | 20 | #### Notes 21 | 22 | * Any DOM nodes inside of the DOM element which you are rendering into will be replaced (i.e., removed). 23 | * `ReactDOM.render()` does not modify the DOM element node in which you are rendering React. However, when rendering React wants complete ownership of the node. You should not add children to or remove children from a node in which React inserts a React node/component. 24 | * Rendering to an HTML DOM is only one option with React, [other rendering APi's are available](https://facebook.github.io/react/docs/top-level-api.html#reactdomserver.rendertostring). For example, it is also possible to render to a string (i.e., `ReactDOMServer.renderToString()`) on the server-side. 25 | * Re-rendering to the same DOM element will only update the current child nodes if a change has been made or a new child node has been added. 26 | -------------------------------------------------------------------------------- /react-nodes/4.4.md: -------------------------------------------------------------------------------- 1 | # Defining Node Attributes/Props 2 | 3 | The second argument that is passed to `React.createElement(type, props, children)` is an object containing name value properties (a.k.a, props). 4 | 5 | Props take on several roles: 6 | 7 | 1. Props can become HTML attributes. If a prop matches a known HTML attribute then it will be added to the final HTML element in the DOM. 8 | 2. Props passed to `createElement()` become values stored in a `prop` object as an instance property of `React.createElement()` instances (i.e., `[INSTANCE].props.[NAME OF PROP]`). Props are normally used to input values into components. 9 | 3. A few special props have side effects (e.g., [`key`](https://facebook.github.io/react/docs/multiple-components.html#dynamic-children), [`ref`](https://facebook.github.io/react/docs/more-about-refs.html), and [`dangerouslySetInnerHTML`](https://facebook.github.io/react/tips/dangerously-set-inner-html.html)) 10 | 11 | In one sense you can think of props as the configuration options for React nodes and in another sense you can think of them as HTML attributes. 12 | 13 | In the code example below I am defining a React `
  • ` element node with five props. One is a non-standard HTML attribute (i.e., `foo:'bar'`) and the others are known HTML attributes. 14 | 15 | ```js 16 | var reactNodeLi = React.createElement('li', 17 | { 18 | foo: 'bar', 19 | id: 'li1', 20 | // Note the use of the JS className property to change the 21 | // class attribute below 22 | className: 'blue', 23 | 'data-test': 'test', 24 | 'aria-role' :'listitem', 25 | // Note use of JS camel-cased CSS property backgroundColor below 26 | style: {backgroundColor:'red'} 27 | }, 28 | 'text' 29 | ); 30 | ``` 31 | 32 | When the above code is rendered to an HTML page the actual HTML created will look like: 33 | 34 | ```html 35 |
  • text
  • 36 | ``` 37 | 38 | What you need to realize is only the following attributes get passed to the real DOM from the Virtual DOM 39 | 40 | * [Standard HTML attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes), 41 | * [Custom data attributes `data-*`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*), and 42 | * [Accessibility attributes `aria-*`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) 43 | 44 | The `foo` attribute/prop does not show up in the real DOM. This non-standard HTML attribute is available as an instance property of the created `li` React node instance. (e.g., `reactNodeLi.props.foo`). 45 | 46 | > [source code](https://jsfiddle.net/codylindley/8ca0z80m/1/#tabs=js,result,html,resources) 47 | 48 | React attributes/props not only translate to real HTML attributes props, they become configuration values that are passed to React components. This aspect of props will be covered in the React component props chapter. For now simply realize that passing a prop into a React node is different from defining a prop on a component to be used as configuration input within a component. 49 | 50 | #### Notes 51 | 52 | * Leaving an attribute/prop blank results in that attribute value becoming true (e.g., `id=""` becomes `id="true"` and `test` becomes `test="true"`) 53 | * If an attribute/prop is duplicated the last one defined wins. 54 | * If you pass props/attributes to native HTML elements that do not exist in the HTML specification React will not render them. However, if you use a custom element (i.e., not a standard HTML element) then arbitrary/custom attributes will be added to custom elements (e.g., ``). 55 | * The `class` attribute has to be written `className` 56 | * The `for` attribute has to be written `htmlFor` 57 | * The `style` attribute takes a reference to an object of [camel-cased style properties](https://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSS2Properties) 58 | * HTML form elements (e.g., ``, ``, etc.) created [as React nodes](https://facebook.github.io/react/docs/forms.html) support a few attributes/props that are affected by user interaction. These are: `value`, `checked`, and `selected`. 59 | * React offers the [`key`](https://facebook.github.io/react/docs/multiple-components.html#dynamic-children), [`ref`](https://facebook.github.io/react/docs/more-about-refs.html), and [`dangerouslySetInnerHTML`](https://facebook.github.io/react/tips/dangerously-set-inner-html.html) attributes/props that don't exist in DOM and take on a unique role/function. 60 | * All attributes are camel-cased (e.g., `accept-charset` is written as `acceptCharset`) which differs from how they are written in HTML. 61 | * The following are the HTML attributes that React supports (shown in camel-case): 62 | 63 | ```HTML 64 | accept acceptCharset accessKey action allowFullScreen allowTransparency alt 65 | async autoComplete autoFocus autoPlay capture cellPadding cellSpacing challenge 66 | charSet checked classID className colSpan cols content contentEditable 67 | contextMenu controls coords crossOrigin data dateTime default defer dir 68 | disabled download draggable encType form formAction formEncType formMethod 69 | formNoValidate formTarget frameBorder headers height hidden high href hrefLang 70 | htmlFor httpEquiv icon id inputMode integrity is keyParams keyType kind label 71 | lang list loop low manifest marginHeight marginWidth max maxLength media 72 | mediaGroup method min minLength multiple muted name noValidate nonce open 73 | optimum pattern placeholder poster preload radioGroup readOnly rel required 74 | reversed role rowSpan rows sandbox scope scoped scrolling seamless selected 75 | shape size sizes span spellCheck src srcDoc srcLang srcSet start step style 76 | summary tabIndex target title type useMap value width wmode wrap 77 | ``` 78 | -------------------------------------------------------------------------------- /react-nodes/4.5.md: -------------------------------------------------------------------------------- 1 | # Inlining CSS on Element Nodes 2 | 3 | To apply inline CSS to a React node you have to pass a `style` attribute/prop with an object value containing CSS properties and values. 4 | 5 | For example, in the code below I am passing a `style` prop referencing (i.e., `inlineStyle`) an object containing CSS properties and values: 6 | 7 | ```js 8 | var inlineStyles = {backgroundColor: 'red', fontSize: 20}; 9 | 10 | var reactNodeLi = React.createElement('div',{style: inlineStyles}, 'styled') 11 | 12 | ReactDOM.render(reactNodeLi, document.getElementById('app1')); 13 | ``` 14 | 15 | The resulting HTML will look like so: 16 | 17 | ```html 18 |
    19 |
    styled
    20 |
    21 | ``` 22 | 23 | Note two things in the JavaScript code above: 24 | 25 | 1. I didn't have to add the "px" to the `fontSize` value because React did it for me. 26 | 2. When writing CSS properties in JavaScript you have to use the [camelCased version of the CSS property](https://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-ElementCSSInlineStyle) (e.g., `backgroundColor` not `background-color`). 27 | 28 | #### Notes 29 | 30 | * Vendor prefixes other than ms should begin with a capital letter. This is why WebkitTransition has an uppercase "W". 31 | * CamelCased CSS properties shouldn't be a surprise given this is how it is done when accessing properties on DOM nodes from JS (e.g., `document.body.style.backgroundImage`) 32 | * When specifying a pixel value React will automatically append the string "px" for you after your number value except for the following properties: 33 | 34 | ```html 35 | columnCount fillOpacity flex flexGrow flexShrink fontWeight 36 | lineClamp lineHeight opacity order orphans strokeOpacity 37 | widows zIndex zoom 38 | ``` 39 | -------------------------------------------------------------------------------- /react-nodes/4.6.md: -------------------------------------------------------------------------------- 1 | # Using Built-in Element Factories 2 | 3 | React provides built-in shortcuts for creating commonly used HTML element nodes. These shortcuts are called React element factories. 4 | 5 | > A ReactElement-factory is simply a function that generates a ReactElement with a particular type property. 6 | 7 | Using a built-in element factory (i.e., `React.DOM.li()`), the React element node `
  • one
  • ` can be created like so: 8 | 9 | ```js 10 | // uses React.DOM.li(props, children); 11 | var reactNodeLi = React.DOM.li({id: 'li1'}, 'one'); 12 | ``` 13 | 14 | instead of using: 15 | 16 | ```js 17 | // uses React.createElement(type, prop, children) 18 | var reactNodeLi = React.createElement('li', {id: 'li1'}, 'one'); 19 | ``` 20 | 21 | Below I list out all of the built in node factories: 22 | 23 | ``` 24 | a,abbr,address,area,article,aside,audio,b,base,bdi,bdo,big,blockquote,body,br,button, 25 | canvas,caption,cite,code,col,colgroup,data,datalist,dd,del,details,dfn,dialog,div,dl, 26 | dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup, 27 | hr,html,i,iframe,img,input,ins,kbd,keygen,label,legend,li,link,main,map,mark,menu, 28 | menuitem,meta,meter,nav,noscript,object,ol,optgroup,option,output,p,param,picture, 29 | pre,progress,q,rp,rt,ruby,s,samp,script,section,select,small,source,span,strong, 30 | style,sub,summary,sup,table,tbody,td,textarea,tfoot,th,thead,time,title,tr,track, 31 | u,ul,var,video,wbr,circle,clipPath,defs,ellipse,g,image,line,linearGradient,mask, 32 | path,pattern,polygon,polyline,radialGradient,rect,stop,svg,text,tspa 33 | ``` 34 | 35 | #### Notes 36 | 37 | * If you are using JSX you might not ever use factories 38 | * React has a built-in helper for you to create custom factories. It's [`React.createFactory(type)`](https://facebook.github.io/react/docs/top-level-api.html#react.createfactory). 39 | -------------------------------------------------------------------------------- /react-nodes/4.7.md: -------------------------------------------------------------------------------- 1 | # Defining React Node Events 2 | 3 | Events can be added to React nodes much like events can be added to DOM nodes. In the code example below I am adding a very simple `click` and `mouseover` event to a React `
    ` node. 4 | 5 | > [source code](https://jsfiddle.net/ct5acw2y/#tabs=js,result,html,resources) 6 | 7 | Note how the property name for an event in React starts with 'on' and is passed in the `props` argument object to the `ReactElement()` function. 8 | 9 | React creates what it calls a [`SyntheticEvent`](https://facebook.github.io/react/docs/events.html) for each event, which contains the details for the event. Similar to the details that are defined for DOM events. The `SyntheticEvent` instance, for an event, is passed into the events handlers/callback functions. In the code below I am logging the details of a SyntheticEvent instance. 10 | 11 | > [source code](https://jsfiddle.net/9yn5qtxu/#tabs=js,result,html,resources) 12 | 13 | Every SyntheticEvent object instance has the following properties. 14 | 15 | ``` 16 | boolean bubbles 17 | boolean cancelable 18 | DOMEventTarget currentTarget 19 | boolean defaultPrevented 20 | number eventPhase 21 | boolean isTrusted 22 | DOMEvent nativeEvent 23 | void preventDefault() 24 | boolean isDefaultPrevented() 25 | void stopPropagation() 26 | boolean isPropagationStopped() 27 | DOMEventTarget target 28 | number timeStamp 29 | string type 30 | ``` 31 | 32 | Additional properties are available depending upon the type/category of event that is used. For example the `onClick` syntheticEvent event also contains the following properties. 33 | 34 | ``` 35 | boolean altKey 36 | number button 37 | number buttons 38 | number clientX 39 | number clientY 40 | boolean ctrlKey 41 | boolean getModifierState(key) 42 | boolean metaKey 43 | number pageX 44 | number pageY 45 | DOMEventTarget relatedTarget 46 | number screenX 47 | number screenY 48 | boolean shiftKey 49 | ``` 50 | 51 | The table below outlines the unique SyntheticEvent properties for each type/category of events. 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 100 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 134 | 135 | 136 | 137 | 138 | 142 | 143 | 144 | 145 | 146 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 174 | 175 | 176 | 177 | 178 | 179 | 184 | 185 | 186 |
    Event Type/Category:Events:Event Specific Properties:

    Clipboard

    onCopy, onCut, onPasteDOMDataTransfer, clipboardData

    Composition

    onCompositionEnd, onCompositionStart, onCompositionUpdatedata

    Keyboard

    onKeyDown, onKeyPress, onKeyUpaltKey, 73 | charCode, 74 | ctrlKey, 75 | getModifierState(key), 76 | key, 77 | keyCode, 78 | locale, 79 | location, 80 | metaKey, 81 | repeat, 82 | shiftKey, 83 | which

    Focus

    onChange, onInput, onSubmitDOMEventTarget, relatedTarget

    Form

    onFocus, onBlur

    Mouse

    onClick, onContextMenu, onDoubleClick, onDrag, onDragEnd, onDragEnter, onDragExit 98 | onDragLeave, onDragOver, onDragStart, onDrop, onMouseDown, onMouseEnter, onMouseLeave 99 | onMouseMove, onMouseOut, onMouseOver, onMouseUpaltKey, 101 | button, 102 | buttons, 103 | clientX, 104 | clientY, 105 | ctrlKey, 106 | getModifierState(key), 107 | metaKey, 108 | pageX, 109 | pageY, 110 | DOMEventTarget relatedTarget, 111 | screenX, 112 | screenY, 113 | shiftKey, 114 |

    Selection

    onSelect

    Touch

    onTouchCancel, onTouchEnd, onTouchMove, onTouchStart 125 | altKey 126 | DOMTouchList changedTouches, 127 | ctrlKey, 128 | getModifierState(key), 129 | metaKey, 130 | shiftKey, 131 | DOMTouchList targetTouches, 132 | DOMTouchList touches, 133 |

    UI

    onScroll 139 | detail, 140 | DOMAbstractView view 141 |

    Wheel

    onWheel 147 | deltaMode, 148 | deltaX, 149 | deltaY, 150 | deltaZ, 151 |

    Media

    onAbort, onCanPlay, onCanPlayThrough, onDurationChange, onEmptied, onEncrypted, onEnded, onError, onLoadedData, onLoadedMetadata, onLoadStart, onPause, onPlay, onPlaying, onProgress, onRateChange, onSeeked, onSeeking, onStalled, onSuspend, onTimeUpdate, onVolumeChange, onWaiting

    Image

    onLoad, onError

    Animation

    onAnimationStart, onAnimationEnd, onAnimationIteration 170 | animationName, 171 | pseudoElement, 172 | elapsedTime 173 |

    Transition

    onTransitionEnd 180 | propertyName, 181 | pseudoElement, 182 | elapsedTime 183 |
    187 | 188 | 189 | #### Notes 190 | 191 | * React normalizes events so that they behave consistently across different browsers. 192 | * Events in React are triggered on the bubbling phase. To trigger an event on the capturing phase add the word "Capture" to the event name (e.g., `onClick` would become `onClickCapture`). 193 | * If you need the browser event details you can access this by using the `nativeEvent` property found in the SyntheticEvent object passed into React event hander/callback. 194 | * React doesn't actually attach events to the nodes themselves, it uses [event delegation](http://domenlightenment.com/#11.14). 195 | * `e.stopPropagation()` or `e.preventDefault()` should be triggered manually to [stop](http://domenlightenment.com/#11.9) event [propagation](http://domenlightenment.com/#11.10) instead of `return false;`. 196 | * Not all DOM events are provided by React. But you can still make use of them [using React lifecycle methods](https://facebook.github.io/react/tips/dom-event-listeners.html). 197 | -------------------------------------------------------------------------------- /react-props.md: -------------------------------------------------------------------------------- 1 | # React Component Properties 2 | 3 | This section will discuss component properties (a.k.a., props). 4 | -------------------------------------------------------------------------------- /react-props/7.1.md: -------------------------------------------------------------------------------- 1 | # What Are Component Props? 2 | 3 | The simplest way to explain component props would be to say that they function similarly to HTML attributes. In other words, props provide configuration values for the component. For example, in the code below a `Badge` component is created and it is expecting a 'name' prop to be sent when the component is instantiated. 4 | 5 | > [source code](https://jsfiddle.net/codylindley/xcL8pff7/1/#tabs=js,result,html,resources) 6 | 7 | Inside the render function of the `` component, where `` is used, the `name` prop is added to the `` component much like an HTML attribute is added to an HTML element (i.e., ``). The `name` prop is then used by the `Badge` component (i.e., `this.props.name`) as the text node for the React `
    ` node rendered by the `Badge` component. This is similar to how an `` can take a value attribute which it uses to display a value. 8 | 9 | Another way to think about component props is that they are the configuration values sent to a component. If you look at the non-JSX version of the previous code example it should be obvious component props are just an object that gets passed to the `createElement()` function (i.e., `React.createElement(Badge, { name: "Bill" })`). 10 | 11 | ```javascript 12 | var Badge = React.createClass({ 13 | displayName: "Badge", 14 | 15 | render: function render() { 16 | return React.createElement( 17 | "div", 18 | null, //no props defined, so null 19 | this.props.name //use passed this.prop.name as text node 20 | ); 21 | } 22 | }); 23 | 24 | var BadgeList = React.createClass({ 25 | displayName: "BadgeList", 26 | 27 | render: function render() { 28 | return React.createElement( 29 | "div", 30 | null, 31 | React.createElement(Badge, { name: "Bill" }), 32 | React.createElement(Badge, { name: "Tom" }) 33 | ); 34 | } 35 | }); 36 | 37 | ReactDOM.render(React.createElement(BadgeList, null), document.getElementById('app')); 38 | ``` 39 | 40 | This is similar to how props can be set directly on React nodes (see 4.4 and 5.7). However, when the `createElement()` function is passed a component definition (i.e., `Badge`) instead of a node, the props become available on the component itself (i.e., `this.props.name`). Component props make it possible to re-use the `` component with any name. 41 | 42 | In the previous code example examined in this section, the `BadgeList` component uses two `Badge` components each with their own `this.props` object. We can verify this by console logging out the value of `this.props` when a `Badge` component is instantiated. 43 | 44 | > [source code](https://jsfiddle.net/codylindley/Lv1zaudj/2/#tabs=js,result,html,resources) 45 | 46 | Basically every React component instance has a unique instance property called `props` that starts as an empty JavaScript object. The empty object can get filled, by a parent component, with any JavaScript value/ reference. These values are then used by the component or passed on to child components. 47 | 48 | #### Notes 49 | 50 | * In ES5 environments/engines you won’t be able to mutate `this.props` because its frozen (i.e., `Object.isFrozen(this.props) === true;` ). 51 | * You should consider `this.props` to be readonly. 52 | -------------------------------------------------------------------------------- /react-props/7.2.md: -------------------------------------------------------------------------------- 1 | # Sending Component Props 2 | 3 | Sending properties to a component entails adding HTML attribute like named values to the component when it is used, not when it is defined. For example, the below `Badge` component is defined first. Then, to send a prop to the `Badge` component, `name="Bill"` is added to the component when it is used (i.e., when `` is rendered). 4 | 5 | ```javascript 6 | var Badge = React.createClass({ 7 | render: function() { 8 | return
    {this.props.name}
    ; 9 | } 10 | }); 11 | 12 | ReactDOM.render(, document.getElementById('app')); 13 | ``` 14 | 15 | Keep in mind anywhere a component is used a property can be sent to it. For example, the code from the previous section demonstrates the use of the `Badge` component and `name` property from within the `BadgeList` component. 16 | 17 | ```javascript 18 | var Badge = React.createClass({ 19 | render: function() { 20 | return
    {this.props.name}
    ; 21 | } 22 | }); 23 | 24 | var BadgeList = React.createClass({ 25 | render: function() { 26 | return (
    27 | 28 | 29 |
    ); 30 | } 31 | }); 32 | 33 | ReactDOM.render(, document.getElementById('app')); 34 | ``` 35 | 36 | #### Notes 37 | 38 | * A components properties should be considered immutable and components should not internally alter the properties sent to them from above. If you need to alter the properties of a component then a re-render should occur; don't set `props` by adding/updating them using `this.props.[PROP] = [NEW PROP]`. 39 | -------------------------------------------------------------------------------- /react-props/7.3.md: -------------------------------------------------------------------------------- 1 | # Getting Component Props 2 | 3 | As discussed in section 6.4 a component instance can be accessed from any configuration option that uses a function by way of the `this` keyword. For example, in the code below the `this` keyword is used to access the `Badge` `props` from the component `render` configuration option (i.e., `this.props.name`). 4 | 5 | ```javascript 6 | var Badge = React.createClass({ 7 | render: function() { 8 | return
    {this.props.name}
    ; 9 | } 10 | }); 11 | 12 | ReactDOM.render(, document.getElementById('app')); 13 | ``` 14 | 15 | Nothing that difficult to grasp is happening if you look at the transformed JavaScript (i.e., JSX to JS) 16 | 17 | ```javascript 18 | var Badge = React.createClass({ 19 | displayName: "Badge", 20 | 21 | render: function render() { 22 | return React.createElement( 23 | "div", 24 | null, 25 | this.props.name 26 | ); 27 | } 28 | }); 29 | 30 | ReactDOM.render(React.createElement(Badge, { name: "Bill" }), document.getElementById('app')); 31 | ``` 32 | 33 | The `{ name: "Bill" }` object is sent to the `createElement()` function along with a reference to the `Badge` component. The value `{ name: "Bill" }` is set as an instance property value of the component accessible from the `props` property (ie. `this.props.name === "Bill"`). 34 | 35 | #### Notes 36 | 37 | * You should consider `this.props` to be readonly, don't set props using `this.props.PROP = 'foo'`. 38 | -------------------------------------------------------------------------------- /react-props/7.4.md: -------------------------------------------------------------------------------- 1 | # Setting Default Component Props 2 | 3 | Default props can be set when a component is being defined by using the `getDefaultProps` configuration value. 4 | 5 | In the code example below, the `Badge` component has a default value for the `name` prop. 6 | 7 | > [source code](https://jsfiddle.net/jv5xrqc4/#tabs=js,result,html,resources) 8 | 9 | Default props will be set on `this.props` if no prop is sent into the component. You can verify this by the fact that the `Badge` component instance with no `name` prop uses the default name `'John Doe'`. 10 | 11 | #### Notes 12 | 13 | * The `getDefaultProps` is invoked once and cached when the component is created. 14 | * The `getDefaultProps` is run before any instances are created thus using `this.props` inside of the `getDefaultProps` will not work. 15 | * Any objects returned by `getDefaultProps()` will be shared across instances, not copied. 16 | -------------------------------------------------------------------------------- /react-props/7.5.md: -------------------------------------------------------------------------------- 1 | # Component Props More Than Strings 2 | 3 | Before looking at validating props one needs to make sure they understand that a component prop can be any valid JavaScript value. 4 | 5 | In the code example below I setup several default props containing several different JavaScript values. 6 | 7 | > [source code](https://jsfiddle.net/u02vckfd/#tabs=js,result,html,resources) 8 | 9 | Note how the `propArray` and `propObject` were overwritten with new values when the `MyComponent` instance is created. 10 | 11 | The main take away here is that you are not limited to string values when passing prop values. 12 | -------------------------------------------------------------------------------- /react-props/7.6.md: -------------------------------------------------------------------------------- 1 | # Validating Component Props 2 | 3 | The enforcement of a prop can be validated when component instances are created. 4 | 5 | When defining a component, the `propTypes` configuration option can be used to identify if and how props should be validated. In the code example below I'm checking to see that `propArray` and `propFunc` are in fact the correct data types and are sent into the component when it is instantiated. 6 | 7 | > [source code](https://jsfiddle.net/jxbdodh8/#tabs=js,result,html,resources) 8 | 9 | I am not sending the correct props as specified using `propTypes` to demonstrate that doing so will cause an error. The above code will result in the following error showing up in the console. 10 | 11 | ``` 12 | Warning: Failed propType: Invalid prop `propArray` of type `object` supplied to `MyComponent`, expected `array` 13 | 14 | Warning: Failed propType: Required prop `propFunc` was not specified in `MyComponent`. 15 | 16 | Uncaught TypeError: this.props.propFunc is not a function 17 | ``` 18 | 19 | Note however, the commented below will not cause an error: 20 | 21 | ```javascript 22 | ReactDOM.render(, document.getElementById('app')); 23 | ``` 24 | 25 | React offers several built in validators (e.g., ` React.PropTypes[VALIDATOR]`) which I outline below (Note that creating custom validators are possible as well.): 26 | 27 | ####Basic type validators: 28 | 29 | These validators check to see if the prop is a specific JS primitive. By default all these are optional. In other words, the validation only occurs if the prop is set. 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
    React.PropTypes.stringIf prop is used, verify it is a string
    React.PropTypes.boolIf prop is used, verify it is a boolean
    React.PropTypes.funcIf prop is used, verify it is a function
    React.PropTypes.numberIf prop is used, verify it is a number
    React.PropTypes.objectIf prop is used, verify it is a object
    React.PropTypes.arrayIf prop is used, verify it is a array
    React.PropTypes.anyIf prop is used, verify it is of any type
    61 | 62 | ####Required type validators: 63 | 64 | 65 | 66 | 67 | 68 | 69 |
    React.PropTypes.[TYPE].isRequiredChaining the .isRequired on to any type validation to make sure the prop is provided (e.g., propTypes:{propFunc:React.PropTypes.func.isRequired} )
    70 | 71 | ####Element validators: 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 82 | 83 |
    React.PropTypes.elementIs a React element.
    React.PropTypes.nodeIs anything that can be rendered: numbers, strings, elements or an array 81 | (or fragment) containing these types.
    84 | 85 | ####Enumerables validators: 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 |
    React.PropTypes.oneOf(['Mon','Fri'])Is one of several types of specific values.
    React.PropTypes.oneOfType([React.PropTypes.string,React.PropTypes.number])Is an object that could be one of many types
    97 | 98 | ####Array and Object validators: 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 |
    React.PropTypes.arrayOf(React.PropTypes.number),Is an array containing only one type of values.
    React.PropTypes.objectOf(React.PropTypes.number)Is an object containing only one type of property values
    React.PropTypes.instanceOf(People)Is object instance of specific constructor(uses `instanceof`)
    React.PropTypes.shape({color:React.PropTypes.string,size: React.PropTypes.number})Is object containing properties having a specific type
    118 | 119 | ####Custom validators: 120 | 121 | 122 | 123 | 124 | 133 | 134 |
    function(props, propName, componentName){}Supply your own function. For example:
    
    125 | 	propTypes: {
    126 | 	  customProp: function(props, propName, componentName) {
    127 | 	    if (!/matchme/.test(props[propName])) {
    128 | 	      return new Error('Validation failed!');
    129 | 	    }
    130 | 	  }
    131 | 	}
    132 | 	
    135 | -------------------------------------------------------------------------------- /react-semantics.md: -------------------------------------------------------------------------------- 1 | # React Semantics 2 | 3 | Before I enlighten you with the mechanics of React I'd first like to define a few terms so as to grease the learning process. 4 | 5 | Below I list the most common terms, and their definitions, used when talking about React. 6 | 7 | #### Babel 8 | [Babel](https://babeljs.io/) transforms JavaScript ES\* (i.e., JS 2016, 2016, 2017) to ES5. Babel is the tool of choice from the React team for writing future ES* code and transforming JSX to ES5 code. 9 | 10 | *** 11 | 12 | #### Babel CLI 13 | Babel comes with a CLI tool, called [Babel CLI](https://babeljs.io/docs/usage/cli/), that can be used to compile files from the command line. 14 | 15 | *** 16 | 17 | #### Component Configuration Options (a.k.a, "Component Specifications") 18 | 19 | The configuration arguments passed (as an object) to the `React.createClass()` function resulting in an instance of a React component. 20 | 21 | *** 22 | 23 | #### Component Life Cycle Methods 24 | 25 | A sub group of component events, semantically separated from the other component configuration options (i.e., `componentWillUnmount`, `componentDidUpdate`, `componentWillUpdate`, `shouldComponentUpdate`, `componentWillReceiveProps`, `componentDidMount`, `componentWillMount`). These methods are executed at specific points in a component's existence. 26 | 27 | *** 28 | 29 | #### Document Object Model (a.k.a., DOM) 30 | 31 | "The Document Object Model (DOM) is a programming interface for HTML, XML and SVG documents. It provides a structured representation of the document as a tree. The DOM defines methods that allow access to the tree, so that they can change the document structure, style and content. The DOM provides a representation of the document as a structured group of nodes and objects, possessing various properties and methods. Nodes can also have event handlers attached to them, and once an event is triggered, the event handlers get executed. Essentially, it connects web pages to scripts or programming languages." - [MSD](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) 32 | 33 | *** 34 | 35 | #### ES5 36 | The 5th edition of the ECMAScript standard. The [ECMAScript 5.1 edition](https://www.ecma-international.org/ecma-262/5.1/) was finalized in June 2011. 37 | 38 | *** 39 | 40 | #### ES6/ES 2015 41 | The 6th edition of the ECMAScript standard. A.k.a, JavaScript 2015 or ECMAScript 2015. The [ECMAScript 6th edition](http://www.ecma-international.org/ecma-262/6.0/index.html) was finalized in June 2015. 42 | 43 | *** 44 | 45 | #### ECMAScript 2016 (a.k.a, ES7) 46 | The 7th edition of the ECMAScript standard. The [ECMAScript 7th edition](http://www.ecma-international.org/ecma-262/7.0/index.html) was finalized in June 2016. 47 | 48 | *** 49 | 50 | #### ES\* 51 | Used to represent the current version of JavaScript as well as potential future versions that can written today using tools like Babel. When you see "ES*" it more than likely means you'll find uses of ES5, ES6, and ES7 together. 52 | 53 | *** 54 | 55 | #### JSX 56 | [JSX](https://jsx.github.io/) is an optional XML-like syntax extension to ECMAScript that can be used to define an HTML-like tree structure in a JavaScript file. The JSX expressions in a JavaScript file must be transformed to JavaScript syntax before a JavaScript engine can parse the file. Babel is typically used and recommended for transforming JSX expressions. 57 | 58 | *** 59 | 60 | #### Node.js 61 | [Node.js](https://nodejs.org/) is an open-source, cross-platform runtime environment for writing JavaScript. The runtime environment interprets JavaScript using [Google's V8 JavaScript engine](https://developers.google.com/v8/). 62 | 63 | *** 64 | 65 | #### npm 66 | [npm](https://www.npmjs.com/) is the package manager for JavaScript born from the Node.js community. 67 | 68 | *** 69 | 70 | #### React Attributes/Props 71 | 72 | In one sense you can think of props as the configuration options for React nodes and in another sense you can think of them as HTML attributes. 73 | 74 | Props take on several roles: 75 | 76 | 1. Props can become HTML attributes. If a prop matches a known HTML attribute then it will be added to the final HTML element in the DOM. 77 | 2. Props passed to `createElement()` become values stored in a `prop` object as an instance property of `React.createElement()` instances (i.e., `[INSTANCE].props.[NAME OF PROP]`). Props by and large are used to input values into components. 78 | 3. A few special props have side effects (e.g., [`key`](https://facebook.github.io/react/docs/multiple-components.html#dynamic-children), [`ref`](https://facebook.github.io/react/docs/more-about-refs.html), and [`dangerouslySetInnerHTML`](https://facebook.github.io/react/tips/dangerously-set-inner-html.html)) 79 | 80 | *** 81 | 82 | #### React 83 | [React](https://facebook.github.io/react/) is an open source JavaScript library for writing declarative, efficient, and flexible user interfaces. 84 | 85 | *** 86 | 87 | #### React Component 88 | 89 | A React component is created by calling `React.createClass()` (or, `React.Component` if using ES6 classes). This function takes an object of options that is used to configure and create a React component. The most common configuration option is the `render` function which returns React nodes. Thus, you can think of a React component as an abstraction containing one or more React nodes/components. 90 | 91 | *** 92 | 93 | #### React Element Nodes (a.k.a., `ReactElement`) 94 | 95 | An HTML or custom HTML element node representation in the Virtual DOM created using `React.createElement();`. 96 | 97 | *** 98 | 99 | #### React Nodes 100 | React nodes (i.e., element and text nodes) are the primary object type in React and can be created using `React.createElement('div');`. In other words React nodes are objects that represent DOM nodes and children DOM nodes. They are a light, stateless, immutable, virtual representation of a DOM node. 101 | 102 | *** 103 | 104 | #### React Node Factories 105 | 106 | A function that generates a React element node with a particular type property. 107 | 108 | *** 109 | 110 | #### React Stateless Function Component 111 | 112 | When a component is purely a result of props alone, no state, the component can be written as a pure function avoiding the need to create a React component instance. 113 | 114 | ``` 115 | var MyComponent = function(props){ 116 | return
    Hello {props.name}
    ; 117 | }; 118 | 119 | ReactDOM.render(, app); 120 | ``` 121 | 122 | *** 123 | 124 | #### React Text Nodes (a.k.a., `ReactText`) 125 | A text node representation in the Virtual DOM created using `React.createElement('div',null,'a text node');`. 126 | 127 | *** 128 | 129 | #### Virtual DOM 130 | An in-memory JavaScript tree of React elements/components that is used for efficient re-rendering (i.e., diffing via JavaScript) of the browser DOM. 131 | 132 | *** 133 | 134 | #### Webpack 135 | 136 | [Webpack](https://webpack.github.io/) is a module loader and bundler that takes modules (.js, .css, .txt, etc.) with dependencies and generates static assets representing these modules. 137 | -------------------------------------------------------------------------------- /react-state.md: -------------------------------------------------------------------------------- 1 | # React Component State 2 | 3 | This section will discuss component state. 4 | -------------------------------------------------------------------------------- /react-state/8.1.md: -------------------------------------------------------------------------------- 1 | # What Is Component State? 2 | 3 | Most components should simply take in props and render. But, components also offer state, and it is used to store information/data about the component that can change over time. Typically the change comes as a result of user events or system events (i.e., as a response to user input, a server request, or the passage of time). 4 | 5 | According to the React documentation state should: 6 | 7 | > Contain data that a component's event handlers may change to trigger a UI update. In real apps this data tends to be very small and JSON-serializable. When building a stateful component, think about the minimal possible representation of its state, and only store those properties in this.state. Inside of render() simply compute any other information you need based on this state. You'll find that thinking about and writing applications in this way tends to lead to the most correct application, since adding redundant or computed values to state means that you need to explicitly keep them in sync rather than rely on React computing them for you. 8 | -------------------------------------------------------------------------------- /react-state/8.2.md: -------------------------------------------------------------------------------- 1 | # Working with Component State 2 | 3 | Working with component state typically involves setting a components default state, accessing the current state, and updating the state. 4 | 5 | In the code example below I am creating a `` that demonstrates the use of `getInitialState`, `this.state.[STATE]`, and `this.setState()`. If you click on the component in a web browser (i.e., the face) then it will cycle through the states (i.e., moods) available. Thus, the component has three potential states, tied to the UI, based on clicks from the UI user. Go ahead and click on the face in the results tab below. 6 | 7 | > [source code](https://jsfiddle.net/codylindley/zr398avp/#tabs=js,result,html,resources) 8 | 9 | Note that the `` has an initial state of ':|', that is set using `getInitialState: function() {return {mood: ':|'};}`, which is used in the component when it is first rendered by writing, `{this.state.mood}`. 10 | 11 | To change the state, an event listener is added; in this case a click event (i.e., `onClick`) on the `` node that will call the `changeMood` function. Within this function I use `this.setState()` to cycle to the next mood based on the current mood/state. After the state is update (i.e., `setState()` merges the changes) the component will re-render itself and the UI will change. 12 | 13 | Things to keep in mind about React component state: 14 | 15 | 1. If a component has state, a default state should be provided using `getInitialState()` 16 | 2. State changes are typically how you start the re-rendering of a component and all sub components (i.e., children, grandchildren, great grand chidlren, etc.). 17 | 3. The only way a component should have its state update should be by using `this.setState()`. While other ways are possible (i.e. `forceUpdate()`), they should likely not be used (except maybe when integrating with third-party solutions). 18 | 4. You inform a component of a state change by using `this.setState()` to set a new state. This will result in re-render of the component and all children components that need re-rendered. 19 | 5. A state change merges new data with old data that is already contained in the state. But this is only a shallow update/merge, it won't do a deep update/merge. 20 | 6. A state change internally deals with calling re-renders. You should never have to call `this.render()` directly. 21 | 7. The state object should only contain the minimal amount of data needed for the UI. Don't place computed data, other React components, or props in the state object. 22 | -------------------------------------------------------------------------------- /react-state/8.3.md: -------------------------------------------------------------------------------- 1 | # State vs. Props 2 | 3 | A components `state` and `props` do share some common ground: 4 | 5 | 1. Both are plain JS objects 6 | 2. Both can have default values 7 | 3. Both should be accessed/read via `this.props` or `this.state`, but neither should be given values this way. I.e., both are readonly when using `this.` 8 | 9 | However they are used for different reasons and in different ways. 10 | 11 | Props: 12 | 13 | 1. Props are passed into a component from above, either a parent component or from the starting scope where React is originally rendered. 14 | 2. Props are intended as configuration values passed into the component. Think of them like arguments passed into a function (If you don't use JSX that is exactly what they are). 15 | 3. Props are immutable to the component receiving them. I.e., don't change props passed to a component from within the component 16 | 17 | State: 18 | 19 | 1. State is a serializable representation of data (a JS object) at one point in time that typically is tied to UI 20 | 2. State should always start with a default value and then the state is mutated internally by the component using `setState()` 21 | 3. State can only be mutated by the component that contains the state. It is private in this sense. 22 | 4. Don't mutate the state of child components. A component should never have shared mutable state. 23 | 5. State should only contain the minimal amount of data needed to represent your UI's state. It should not contain computed data, other React components, or duplicated data from props. 24 | 6. State should be avoided if at all possible. I.e., stateless components are ideal, stateful components add complexity. The React documentation suggest: "A common pattern is to create several stateless components that just render data, and have a stateful component above them in the hierarchy that passes its state to its children via props. The stateful component encapsulates all of the interaction logic, while the stateless components take care of rendering data in a declarative way." 25 | -------------------------------------------------------------------------------- /react-state/8.4.md: -------------------------------------------------------------------------------- 1 | # Creating Stateless Function Components 2 | 3 | When a component is purely a result of `props` alone, no `state`, the component can be written as a pure function avoiding the need to create a React component instance. In the code example below `MyComponent` is the result of a function that returns the results from `React.createElement()`. 4 | 5 | > [source code](https://jsfiddle.net/5nzpxyuu/#tabs=js,result,html,resources) 6 | 7 | Having look at the same code not using JSX should clarify what is going on. 8 | 9 | ```js 10 | var MyComponent = function MyComponent(props) { 11 | return React.createElement( 12 | "div", 13 | null, 14 | "Hello ", 15 | props.name 16 | ); 17 | }; 18 | 19 | ReactDOM.render(React.createElement(MyComponent, { name: "doug" }), app); 20 | ``` 21 | 22 | Constructing a React component without calling `React.createClass()` is typically referred to as a stateless function component. 23 | 24 | Stateless function components can't be passed component options (i.e., `render`, `componentWillUnmount`, etc.). However `.propTypes` and `.defaultProps` can be set as properties on the function. 25 | 26 | The code example below demonstrates a stateless function component making use of `.propTypes` and `.defaultProps`. 27 | 28 | > [source code](https://jsfiddle.net/tpvjyp34/#tabs=js,result,html,resources) 29 | 30 | #### Notes 31 | 32 | * Make as many of your components as possible, as stateless components. 33 | -------------------------------------------------------------------------------- /scripts/pathway.js: -------------------------------------------------------------------------------- 1 | !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else{var n=t();for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}(this,(function(){return function(){"use strict";var e={d:function(t,n){for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})}};e.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),e.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},e.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var t={};e.r(t),e.d(t,{RM:function(){return le}});var n=0,r={token:"empty token",errorCount:0,tjsToken:"8de4c78a3ec64020ab2ad15dea1ae9ff",tjsApp:"rmagent",tjsVersion:"3.6.0",getErrorUrl:function(){return"https://capture.trackjs.com/capture?token="+r.tjsToken+"&v="+r.tjsVersion+"&source=rm"},error:function(e,t){if(void 0===t&&(t=null),!(n>=2)){var i=e||{},o=i.message||"empty",s=i.stack||(new Error).stack;r.errorCount++;var a=(self.location||"").toString(),c={agentPlatform:"browser",console:[{message:JSON.stringify(e),severity:"log",timestamp:(new Date).toISOString()}],customer:{token:r.tjsToken,application:r.tjsApp,userId:r.token,version:"1.13.1"},entry:"catch",environment:{originalUrl:a,userAgent:navigator.userAgent},message:o,url:a,stack:s,timestamp:(new Date).toISOString(),version:r.tjsVersion};null!=t&&c.console.push({message:t,severity:"log",timestamp:(new Date).toISOString()});var u=new XMLHttpRequest;u.open("POST",r.getErrorUrl()),u.send(JSON.stringify(c)),n++}}};function i(){return"undefined"==typeof document}function o(e){return(e=e||"").indexOf("?")>=0&&(e=e.split("?")[0]),e.length>=1e3&&(e=e.substr(0,1e3)),e}function s(e,t){if((e=""+e).length<=t)return e;var n=e.length-t;return e.substr(0,t)+"...{"+n+"}"}function a(e,t){return void 0===t&&(t=0),parseFloat(e.toFixed(t))}var c=["com","net","gov","edu","org"];function u(e,t,n){var r=e[t]||l;e[t]=n(r)}function l(){}function p(){return Math.floor(1e3*(Date.now()+Math.random()))}function f(e,t){try{for(var n=t.split("."),r=e,i=0;i25?delete e[t]:e[t]=s(e[t],100)})),e}function h(e){return Object.prototype.toString.call(e)}function g(e){return v(e)&&1===e.nodeType}function m(e){return"number"==typeof e||v(e)&&"[object Number]"===h(e)}function v(e){return!(!e||"object"!=typeof e)}function y(e){return"string"==typeof e||!function(e){return"[object Array]"===h(e)}(e)&&v(e)&&"[object String]"===h(e)}function w(e){if(!v(e))return!1;var t=h(e);return"[object Error]"===t||"[object DOMException]"===t||y(e.name)&&y(e.message)}function S(e){function t(e){for(var t="<"+e.tagName.toLowerCase(),n=e.attributes||[],r=0;r"}var n,r="undefined";if(""===e)return"Empty String";if(void 0===e)return r;if(y(e)||m(e)||function(e){return"boolean"==typeof e||v(e)&&"[object Boolean]"===h(e)}(e)||function(e){return!(!e||"function"!=typeof e)}(e))return""+e;if(g(e))return t(e);if("symbol"==typeof e)return Symbol.prototype.toString.call(e);try{n=JSON.stringify(e,(function(e,n){return void 0===n?r:m(n)&&isNaN(n)?"NaN":w(n)?{name:n.name,message:n.message,stack:n.stack}:g(n)?t(n):n}))}catch(t){var i="";for(var o in e)if(e.hasOwnProperty(o))try{i+=',"'+o+'":"'+e[o]+'"'}catch(e){}n=i?"{"+i.replace(",","")+"}":"Unserializable Object"}return n.replace(/"undefined"/g,r).replace(/"NaN"/g,"NaN")}function E(e){if(!e)return"";if((e=e.toString()).startsWith("http")||i())return e;try{return new URL(e,document.baseURI).toString()}catch(t){return e}}var T,b,R,_,k=new(function(){function t(){var e=this;this.apiEntries=[],this.addEntry=function(t){t.url&&0===t.url.indexOf("http")&&(e.options.monitorSelfCalls||0!==t.url.indexOf(e.options.ingestUrl))&&e.apiEntries.push(t)}}return t.prototype.install=function(e){this.options=e,this.wrapFetch(),this.wrapXhr()},t.prototype.getApis=function(e){if(void 0===e&&(e=!1),e||this.apiEntries.length>=10){var t=this.apiEntries;return this.apiEntries=[],t}return[]},t.prototype.wrapFetch=function(){var t=this;u(e.g,"fetch",(function(n){return function(r,s){var c=r instanceof Request?r.url:r,u=r instanceof Request?r.method:(s||{}).method||"GET",l=n.apply(e.g,arguments);return l.__rm_state__={source:i()?"worker":"fetch",startedOn:a(performance.now()),method:u,requestUrl:E(c),pageUrl:o(self.location.toString())},l.then((function(e){var n=l.__rm_state__;if(n){var r=performance.now(),i={source:n.source,method:n.method,startedOn:n.startedOn,pageUrl:n.pageUrl,duration:a(r)-n.startedOn,statusCode:e.status,contentLength:e.headers.get("content-length"),contentType:e.headers.get("content-type"),url:e.url||n.requestUrl};t.addEntry(i)}return e})).catch((function(e){var n=l.__rm_state__;if(n){var r=performance.now(),i={source:n.source,method:n.method,startedOn:n.startedOn,pageUrl:n.pageUrl,duration:a(r)-n.startedOn,statusCode:0,contentLength:null,contentType:null,url:n.requestUrl};t.addEntry(i)}throw e}))}}))},t.prototype.wrapXhr=function(){if(!i()){var e=this;u(XMLHttpRequest.prototype,"open",(function(e){return function(t,n){var r=this;return r.__rm_state__={source:"xhr",method:t,requestUrl:E((n||"").toString())},e.apply(r,arguments)}})),u(XMLHttpRequest.prototype,"send",(function(t){return function(){var n=this,r=n.__rm_state__;return r?(n.__rm_state__=Object.assign(r,{startedOn:a(performance.now()),pageUrl:o(self.location.toString())}),n.addEventListener("readystatechange",(function(){if(4===n.readyState){var t=n.__rm_state__,r=performance.now(),i={source:t.source,method:t.method,startedOn:t.startedOn,pageUrl:t.pageUrl,duration:a(r)-t.startedOn,statusCode:n.status,url:n.responseURL||t.requestUrl,contentLength:n.getResponseHeader("content-length"),contentType:n.getResponseHeader("content-type")};e.addEntry(i)}}),!0),t.apply(n,arguments)):t.apply(n,arguments)}}))}},t}()),C=new(function(){function e(){this.errorEntries=[]}return e.prototype.install=function(e){this.options=e,this.watchGlobal(),this.watchPromise(),this.wrapConsole()},e.prototype.getErrors=function(e){if(void 0===e&&(e=!1),e||this.errorEntries.length>=1){var t=this.errorEntries;return this.errorEntries=[],t}return[]},e.prototype.addError=function(e){null!=e.message&&0!==e.message.toString().indexOf("Script error")&&this.errorEntries.push(e)},e.prototype.watchGlobal=function(){self.addEventListener("error",(function(e){try{if(!e||!e.error)return;C.addError({name:e.error.name,message:e.error.message,stack:e.error.stack,cause:e.error.cause?S(e.error.cause):void 0,time:a(performance.now()),entry:"global",pageUrl:self.location.toString()})}catch(e){r.error(e,"global error handler")}}))},e.prototype.watchPromise=function(){self.addEventListener("unhandledrejection",(function(e){try{if(!e)return;var t=e.reason;if(null==t)return;w(t)||(t=new Error(S(t))),C.addError({name:t.name,message:t.message,stack:t.stack,cause:t.cause?S(t.cause):void 0,time:a(performance.now()),entry:"promise",pageUrl:self.location.toString()})}catch(e){r.error(e,"promise error handler")}}))},e.prototype.wrapConsole=function(){u(self.console,"error",(function(e){return function(){try{var t,n=Array.prototype.slice.call(arguments);t=1===n.length&&w(n[0])?n[0]:new Error(1===n.length?S(n[0]):S(n)),C.addError({name:t.name,message:t.message,stack:t.stack,cause:t.cause?S(t.cause):void 0,time:a(performance.now()),entry:"console",pageUrl:self.location.toString()})}catch(e){r.error(e,"console error handler")}return e.apply(this,arguments)}}))},e}()),O="__rm_sid__",I="__rm_sid_ts__",L={_sessionId:0,_storageDisabled:!1,getSessionId:function(){if(!self.performance)return 0;var e=Date.now(),t=0;if(this._storageDisabled&&this._sessionId)return this._sessionId;try{this._sessionId=parseInt(localStorage.getItem(O),10),t=parseInt(localStorage.getItem(I),10)}catch(e){this._storageDisabled=!0}if(!this._sessionId||this.isSessionExpired(e,t)){this._sessionId=p(),j.addEvent({name:"session_start",time:a(performance.now()),pageUrl:self.location.toString(),referrer:i()?"":document.referrer});try{localStorage.setItem(O,this._sessionId.toString()),this.refreshSession()}catch(e){this._storageDisabled=!0}}return this._sessionId},refreshSession:function(){try{localStorage.setItem(I,Date.now().toString())}catch(e){}},isSessionExpired:function(e,t){return!t||t+18e5=1){var t=this.eventEntries;return this.eventEntries=[],t}return[]},e.prototype.addEvent=function(e){L.refreshSession(),this.eventEntries.push(e)},e.prototype.wrapActivity=function(){i()||(document.addEventListener("click",this.onDocumentClicked,!0),document.addEventListener("blur",this.onInputChanged,!0),document.addEventListener("scroll",this.onFirstScroll,{once:!0,capture:!0,passive:!0}))},e.prototype.wrapHistory=function(){var e=this;if(this.isCompatible()){var t=this;self.addEventListener("popstate",(function(){e.addEvent({name:"popstate",time:a(performance.now()),pageUrl:self.location.toString()})}),!0),u(history,"pushState",(function(e){return function(){var n=e.apply(this,arguments);return t.addEvent({name:"pushState",time:a(performance.now()),pageUrl:self.location.toString()}),n}}))}},e.prototype.isCompatible=function(){return!i()&&!f(self,"chrome.app.runtime")&&f(self,"addEventListener")&&f(self,"history.pushState")},e.prototype.onSelectInputChanged=function(e){if(e.multiple)for(var t=0;t=0&&e.options[e.selectedIndex]&&this.writeActivityEvent(e,"input",e.options[e.selectedIndex].value)},e.prototype.writeActivityEvent=function(e,t,n,r){"password"===this.getElementType(e)&&(n=void 0),this.addEvent({name:t,time:a(performance.now()),pageUrl:self.location.toString(),element:{tag:e.tagName.toLowerCase(),attributes:this.getElementAttributes(e),value:this.getMetaValue(n,r),text:e.innerText?s(e.innerText,100):""}})},e.prototype.getElementFromEvent=function(e){return e.target||document.elementFromPoint(e.clientX,e.clientY)},e.prototype.getDescribedElement=function(e,t,n){if(e.closest){if(!(e=e.closest(t)))return null}else if(e.tagName.toLowerCase()!==t.toLowerCase())return null;if(!n)return e;for(var r=this.getElementType(e),i=0;i=0}))},e.prototype.binResources=function(e){var t=this,n=[],r=[],i=[],o=[],s=[],a=[];return e.forEach((function(e){t.isImage(e)?n.push(e):t.isScript(e)?r.push(e):t.isXhr(e)?i.push(e):t.isCss(e)?o.push(e):t.isFont(e)?s.push(e):a.push(e)})),{allImages:n,allScripts:r,allXhr:i,allCss:o,allFonts:s,allOther:a}},e.prototype.isImage=function(e){if("img"===e.initiatorType)return!0;try{if("css"===e.initiatorType||"link"===e.initiatorType){var t=new URL(e.name).pathname.toLowerCase();return[".jpg",".jpeg",".png",".gif",".svg",".raw",".webp",".heif",".avif"].some((function(e){return t.endsWith(e)}))}}catch(e){}return!1},e.prototype.isScript=function(e){if("script"===e.initiatorType)return!0;try{if("link"===e.initiatorType||"other"===e.initiatorType)return new URL(e.name).pathname.toLowerCase().endsWith(".js")}catch(e){}return!1},e.prototype.isXhr=function(e){return"fetch"===e.initiatorType||"xmlhttprequest"===e.initiatorType},e.prototype.isCss=function(e){if("link"!==e.initiatorType&&"css"!==e.initiatorType)return!1;try{return new URL(e.name).pathname.toLowerCase().endsWith("css")}catch(e){}return!1},e.prototype.isFont=function(e){if("link"!==e.initiatorType&&"css"!==e.initiatorType&&"other"!==e.initiatorType)return!1;try{var t=new URL(e.name).pathname.toLowerCase();return[".woff",".woff2",".ttf",".eot",".otf"].some((function(e){return t.endsWith(e)}))}catch(e){}return!1},e.prototype.isThirdParty=function(e){try{return new URL(e).origin!==self.location.origin}catch(e){}return!1},e.prototype.getWallClockTimeForResources=function(e){return a(this.getTimeRangesForResources(e).reduce((function(e,t){return e+t.duration}),0))},e.prototype.getTimeRangesForResources=function(e){e=e.sort((function(e,t){return e.startTime-t.startTime}));var t=[];return e.forEach((function(e){var n=t[t.length-1];n&&n.isWithinRange(e)?n.applyTiming(e):t.push(new F(e))})),t},e.prototype.sentResources=function(){this.hasSent=!0,e.cachedResourceTimings=null},e.cachedResourceTimings=null,e}(),F=function(){function e(e){this.start=e.startTime,this.end=e.responseEnd}return Object.defineProperty(e.prototype,"duration",{get:function(){return this.end-this.start},enumerable:!1,configurable:!0}),e.prototype.isWithinRange=function(e){return e.startTime<=this.end},e.prototype.applyTiming=function(e){this.end=0?r="back-forward-cache":n&&(r=document.prerendering||B()>0?"prerender":n.type.replace(/_/g,"-")),{name:e,value:void 0===t?-1:t,rating:"good",delta:0,entries:[],id:"v3-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},H=function(e,t,n){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){t(e.getEntries())}));return r.observe(Object.assign({type:e,buffered:!0},n||{})),r}}catch(e){}},z=function(e,t){var n=function n(r){"pagehide"!==r.type&&"hidden"!==document.visibilityState||(e(r),t&&(removeEventListener("visibilitychange",n,!0),removeEventListener("pagehide",n,!0)))};addEventListener("visibilitychange",n,!0),addEventListener("pagehide",n,!0)},W=function(e,t,n,r){var i,o;return function(s){t.value>=0&&(s||r)&&((o=t.value-(i||0))||void 0===i)&&(i=t.value,t.delta=o,t.rating=function(e,t){return e>t[1]?"poor":e>t[0]?"needs-improvement":"good"}(t.value,n),e(t))}},V=-1,X=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},$=function(){z((function(e){var t=e.timeStamp;V=t}),!0)},Q=function(){return V<0&&(V=X(),$(),D((function(){setTimeout((function(){V=X(),$()}),0)}))),{get firstHiddenTime(){return V}}},J=function(e,t){t=t||{};var n,r=[1800,3e3],i=Q(),o=N("FCP"),s=function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(c&&c.disconnect(),e.startTime=0&&b1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,t){var n=function(){ee(e,t),i()},r=function(){i()},i=function(){removeEventListener("pointerup",n,Z),removeEventListener("pointercancel",r,Z)};addEventListener("pointerup",n,Z),addEventListener("pointercancel",r,Z)}(t,e):ee(t,e)}},re=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(t){return e(t,ne,Z)}))},ie={},oe=function(){function e(){var e=this;this.vitalsSent=!1,this.metricQueue=new Set,this.addToQueue=function(t){e.metricQueue.add(t)},i()||(function(e,t){t=t||{};var n=[.1,.25];Y||(J((function(e){G=e.value})),Y=!0);var r,i=function(t){G>-1&&e(t)},o=N("CLS",0),s=0,a=[],c=function(e){e.forEach((function(e){if(!e.hadRecentInput){var t=a[0],n=a[a.length-1];s&&e.startTime-n.startTime<1e3&&e.startTime-t.startTime<5e3?(s+=e.value,a.push(e)):(s=e.value,a=[e]),s>o.value&&(o.value=s,o.entries=a,r())}}))},u=H("layout-shift",c);u&&(r=W(i,o,n,t.reportAllChanges),z((function(){c(u.takeRecords()),r(!0)})),D((function(){s=0,G=-1,o=N("CLS",0),r=W(i,o,n,t.reportAllChanges)})))}(this.addToQueue,{reportAllChanges:!0}),function(e,t){t=t||{};var n,r=[100,300],i=Q(),o=N("FID"),s=function(e){e.startTime=50||n.duration<=0||"xmlhttprequest"!==n.initiatorType&&"fetch"!==n.initiatorType)){var i=o(n.name);if(function(e,t){var n=function(e){try{if(!e||0!==e.indexOf("http"))return null;var t=new URL(e).hostname;if(!t)return null;var n=t.split("."),i=n.pop();if("localhost"===i)return i;if("127.0.0.1"===t)return t;var o=n.pop();return 2===o.length&&(o=n.pop()),c.indexOf(o)>=0&&(o=n.pop()),"".concat(o,".")}catch(t){return r.error(t,"Page Url: ".concat(e)),null}}(t);if(!n)return!1;try{var i=new URL(e).hostname;return!!i&&i.indexOf(n)>=0}catch(t){return r.error(t,"Problem parsing first party url: ".concat(e)),!1}}(i,self.location.toString())){var s=i+n.startTime;e.entryHash[s]||(e.options.monitorSelfCalls||0!==e.getIngestUrl().indexOf(i))&&(r.errorCount>0&&0===r.getErrorUrl().indexOf(i)||(e.entryHash[s]=!0,t.push({url:i,start:a(n.startTime),duration:a(n.duration)})))}}})),t},e.prototype.getDevice=function(){try{if(/Mobi|Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent))return"mobile"}catch(e){}return"desktop"},e.prototype.getNetworkType=function(){try{var e=null===navigator||void 0===navigator?void 0:navigator.connection;return e?"".concat(e.effectiveType,":").concat(e.downlink,":").concat(e.rtt):null}catch(e){return null}},e.prototype.getPayload=function(e){var t;return void 0===e&&(e=!1),this.endpoints=this.endpoints.concat(this.getEndpointEntries()),{token:this.options.token,timeOrigin:new Date(this.timeOrigin).toISOString(),timeSent:(new Date).toISOString(),device:this.getDevice(),pageViewId:this.pageViewId,sessionId:this.sessionId,page:this.pageService.getPageEntry(),endpoints:ae([],this.endpoints,!0),vitals:null===(t=this.webVitalsObserver)||void 0===t?void 0:t.getVitals(this.pageService.getPageUrl()),resources:this.resourceService.getResources(),tags:this.options.tags,metadata:this.metadata,networkType:this.getNetworkType(),api:k.getApis(e),events:j.getEvents(e),errors:C.getErrors(e),js:this.resourceService.getAllThirdPartyJs(),env:{lang:navigator.language,width:i()?null:null===screen||void 0===screen?void 0:screen.width,height:i()?null:null===screen||void 0===screen?void 0:screen.height,dpr:i()?null:null===window||void 0===window?void 0:window.devicePixelRatio},user:this.user}},e.prototype.payloadHasData=function(e){return!(this.shutdownSend||this.sendCount>=60||!e||!(e.page||e.endpoints.length||e.vitals||e.resources||e.api.length||e.events.length||e.errors.length||e.js.length))},e.prototype.shouldSendInterval=function(e){return!!this.payloadHasData(e)&&!!(e.page||e.vitals||e.resources||i()||e.endpoints.length>=10||e.api.length>0||e.events.length>0||e.errors.length>0||e.js.length>0)},e.prototype.checkAndSend=function(){var e=this;try{var t=this.getPayload();if(t.source="polling",!this.shouldSendInterval(t))return;this.clearPayloadAfterSend(t);var n=new XMLHttpRequest;n.open("POST",this.getIngestUrl()),n.setRequestHeader("Content-Type","application/json"),n.addEventListener("load",(function(){n.status>=400&&(e.shutdownSend=!0)})),n.send(JSON.stringify(t))}catch(e){r.error(e)}},e.prototype.clearPayloadAfterSend=function(e){var t;this.sendCount++,this.endpoints.length=0,e.page&&this.pageService.sentPage(),e.vitals&&(null===(t=this.webVitalsObserver)||void 0===t||t.sentVitals()),e.resources&&this.resourceService.sentResources()},e.prototype.manageResourceBuffer=function(){var e=this;performance.setResourceTimingBufferSize&&performance.setResourceTimingBufferSize(1e3);var t=function(t){e.resourceService.cacheResources(),performance.clearResourceTimings()};if(performance.addEventListener)try{performance.addEventListener("resourcetimingbufferfull",t)}catch(e){}else performance.onresourcetimingbufferfull=t},e.defaults={token:null,ingestUrl:"https://in.requestmetrics.com/v1",monitorSelfCalls:!1,tags:[]},e}(),ue={__agent:null,version:"1.13.1",install:function(e){try{if(ue.__agent)return void console.warn("Request Metrics is already installed.");if("undefined"==typeof self)return void console.warn("Request Metrics does not operate in this environment.");if(!e||!e.token)return void console.error("You must provide a token to install Request Metrics.");r.token=e.token,ue.__agent=new ce(e)}catch(e){r.error(e)}},identify:function(e,t){try{return ue.__agent?e?ue.__agent.identify(e,t):void console.warn("You must provide a userId."):void console.warn("Request Metrics isn't installed.")}catch(e){r.error(e)}},sendEvent:function(e,t,n){void 0===n&&(n=null);try{return ue.__agent?e?ue.__agent.sendEvent(e,t,n):void console.warn("You must provide an event name."):void console.warn("Request Metrics isn't installed.")}catch(e){r.error(e)}},track:function(e,t,n){void 0===n&&(n=null);try{return ue.__agent?w(e)?ue.__agent.track(e,t,n):void console.warn("You must provide an instance of Error"):void console.warn("Request Metrics isn't installed.")}catch(e){r.error(e)}},addMetadata:function(e){try{if(!ue.__agent)return void console.warn("Request Metrics isn't installed.");if(!e)return;return ue.__agent.addMetadata(e)}catch(e){r.error(e)}}},le=ue;return function(){try{if(i())return;if(!document.querySelector)return;if(self.RM&&self.RM._options)return ue.install(self.RM._options),self.RM._userId&&ue.identify(self.RM._userId,self.RM._identifyOptions),self.RM._events&&self.RM._events.forEach((function(e){ue.sendEvent(e.eventName,e.metadata,e.time)})),self.RM._errors&&self.RM._errors.forEach((function(e){ue.track(e.error,e.metadata,e.time)})),void(self.RM._metadata&&ue.addMetadata(self.RM._metadata));var e=document.querySelector("[data-rm-token]");if(!e)return;var t=e.getAttribute("data-rm-token");if(!t)return;var n=(e.getAttribute("data-rm-tags")||"").split(",").filter((function(e){return e}));r.token=t,ue.install({token:t,ingestUrl:e.getAttribute("data-rm-ingest"),monitorSelfCalls:!!e.getAttribute("data-rm-monitor-self"),tags:n});var o=e.getAttribute("data-rm-userId");o&&ue.identify(o)}catch(e){r.error(e)}}(),t}()})); 2 | 3 | if (location.host === "frontendmasters.com") { 4 | RM.install({ 5 | token: "b4dw8ec:b9ht8wy", 6 | ingestUrl: "https://pathway.frontendmasters.com/v1", 7 | }); 8 | } 9 | -------------------------------------------------------------------------------- /styles/ebook.css: -------------------------------------------------------------------------------- 1 | cite{ 2 | margin-top: -30px; 3 | font-size:10px; 4 | text-align: center; 5 | color: #666; 6 | } 7 | 8 | .page-inner ul, .page-inner ol { 9 | margin-bottom:15px !important; 10 | } 11 | 12 | .book .book-body .page-wrapper .page-inner section.normal hr { 13 | height: 1px; 14 | padding: 0; 15 | margin: 0.7em 0; 16 | overflow: hidden; 17 | background-color: #e7e7e7; 18 | border: none; 19 | } 20 | 21 | table code, .markdown-section table code { 22 | background-color: transparent !important; 23 | } 24 | -------------------------------------------------------------------------------- /styles/website.css: -------------------------------------------------------------------------------- 1 | body { 2 | display: flex; 3 | flex-direction: column; 4 | } 5 | 6 | cite{ 7 | margin-top: -30px; 8 | font-size:10px; 9 | text-align: center; 10 | color: #666; 11 | } 12 | 13 | .page-inner ul, .page-inner ol { 14 | margin-bottom:15px !important; 15 | } 16 | 17 | .book .book-body .page-wrapper .page-inner section.normal hr { 18 | height: 1px; 19 | padding: 0; 20 | margin: 0.7em 0; 21 | overflow: hidden; 22 | background-color: #e7e7e7; 23 | border: none; 24 | } 25 | 26 | table code, .markdown-section table code { 27 | background-color: transparent !important; 28 | } 29 | 30 | small{ 31 | font-size:10px; 32 | } 33 | 34 | .FmCta { 35 | align-items: flex-start; 36 | background: #000; 37 | color: #fff; 38 | display: flex; 39 | gap: 15px; 40 | line-height: 2; 41 | padding: 10px 15px; 42 | } 43 | 44 | .FmCtaLogo svg { 45 | fill: #c02d28; 46 | vertical-align: middle; 47 | width: 25px; 48 | } 49 | 50 | .FmCtaLogo:hover svg { 51 | fill: #dd625e; 52 | } 53 | 54 | .FmCtaText { 55 | display: flex; 56 | flex: 1; 57 | gap: 15px; 58 | } 59 | 60 | .FmCtaText a { 61 | color: #ccc; 62 | font-weight: bold; 63 | } 64 | 65 | .FmCtaText a:hover { 66 | color: #fff; 67 | } 68 | 69 | .FmCtaClose { 70 | background: none; 71 | border: none; 72 | color: #888; 73 | font-size: 25px; 74 | height: 30px; 75 | line-height: 1; 76 | outline: none; 77 | padding-bottom: 5px; 78 | width: 30px; 79 | } 80 | 81 | .FmCtaClose:hover { 82 | color: #fff; 83 | } -------------------------------------------------------------------------------- /template.md: -------------------------------------------------------------------------------- 1 | # Title [Use Title-Casing] 2 | 3 | Utilize the AP style for title-casing. 4 | 5 | --- 6 | 7 | 8 | ## Sub [Use Title-Casing] 9 | 10 | Utilize the AP style for sub-title-casing. 11 | 12 | --- 13 | 14 | 15 | > [source code](https://jsfiddle.net/bvpe4j39/#height=600) 16 | 17 | 18 | --- 19 | 20 | 21 | ### Punctuation in Abbreviations 22 | 23 | Use proper punctuation in Latin abbreviations: 24 | 25 | * ex.: (if beginning a sentence use a capital "E": Ex.:) 26 | * e.g., (if beginning a sentence use a capital "E": E.g.,) 27 | * i.e., (if beginning a sentence use a capital "I": I.e.,) 28 | * etc., 29 | * et al. 30 | 31 | --- 32 | 33 | 34 | ### Code Snippets 35 | 36 | Use backticks (`) for code snippts. Ex.: `createElement` will be rendered as `createElement`. -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var Timer = React.createClass({ 2 | getInitialState: function() { 3 | return { 4 | secondsElapsed: Number(this.props.startTime) || 0 5 | }; 6 | }, 7 | tick: function() { 8 | this.setState({ 9 | secondsElapsed: this.state.secondsElapsed + 1 10 | }); 11 | }, 12 | componentDidMount: function() { 13 | this.interval = setInterval(this.tick, 1000); 14 | }, 15 | componentWillUnmount: function() { 16 | clearInterval(this.interval); 17 | }, 18 | render: function() { 19 | return ( 20 |
    21 | Seconds Elapsed: {this.state.secondsElapsed} 22 |
    23 | ); 24 | } 25 | }); 26 | ReactDOM.render(< Timer startTime = "60" / >, app); 27 | -------------------------------------------------------------------------------- /what-is-react.md: -------------------------------------------------------------------------------- 1 | # What is React? 2 | 3 | React is a JavaScript tool that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. It provides the means to declaratively define and divide a UI into UI components (a.k.a., React components) using HTML-like nodes called React nodes. React nodes eventually get transformed into a format for UI rendering (e.g., HTML/DOM, canvas, svg, etc.). 4 | 5 | I could ramble on trying to express in words what React is, but I think it best to just show you. What follows is a whirlwind tour of React and React components from thirty thousand feet. Don't try and figure out all the details yet as I describe React in this section. The entire book is meant to unwrap the details showcased in the following overview. Just follow along grabbing a hold of the big concepts for now. 6 | 7 | ## Using React to create UI components similar to a `` element that encapsulates child HTML `