├── GTD └── Getting Things Done.markdown ├── HTML+CSS └── Introductory HTML and CSS.markdown ├── JavaScript ├── EqualityOfObjectsAndArraysInJavaScript.markdown ├── IntroductoryJSArrayObject.markdown └── PassByReferenceandValue.markdown ├── LICENSE ├── PHP └── Introductory Array Exercises.markdown ├── README.md └── React.js ├── IntroductoryReact.markdown └── WhenDoesReactCallRender.markdown /GTD/Getting Things Done.markdown: -------------------------------------------------------------------------------- 1 | # Getting Things Done 2 | 3 | A good(?) summary video: https://www.youtube.com/watch?v=NnnaJkKdwjU 4 | 5 | - **"Your mind is for having ideas, not holding them."** 6 | - Have a system for remembering other than your brain. Doesn't matter *what* as much as it matters that you trust it, you use it, and it is fast & easy. 7 | - You don't have to worry about forgetting things. 8 | - You can focus on the one task at hand without being distracted by everything else. 9 | - **Have an "inbox" where you can throw all your ideas, immediately, when you have them.** 10 | - I find paper often works best for this, as switching apps tends to be too slow & distracting. 11 | - You may have multiple inboxes (i.e. paper, digital, etc.) 12 | - Email is just an inbox, not a to-do list. 13 | - Don't organize yet, that's distracting. 14 | - **Regularly go through the inbox to put things in their right place:** 15 | - if you can completely take care of it in 2 minutes, just do it 16 | - some stuff is trash 17 | - some stuff you wait for others for or need to be reminded later—calendar alert or similar 18 | - some stuff just needs to be filed for reference 19 | - otherwise, pick the next actionable thing you can do, put it on your to-do list, and file it away 20 | - **Regularly go through the to-do list, and:** 21 | - remove stuff that doesn't matter 22 | - prioritize what needs to be done next 23 | - some things get delegated to a "someday, maybe" list: good ideas, just not now 24 | - **Do stuff!** 25 | - some tasks require a certain location or tools; do them when you are there 26 | - do small tasks when have small time slot, larger tasks when larger 27 | - do hard tasks when you have lots of energy, easy tasks when you don't 28 | - prioritize by importance 29 | 30 | (adapted from the http://joebuhlig.com/getting-things-done-introduction/ series, adapted from David Allen's Getting Things Done) -------------------------------------------------------------------------------- /HTML+CSS/Introductory HTML and CSS.markdown: -------------------------------------------------------------------------------- 1 | # Introductory HTML and CSS 2 | 3 | This document is an attempt to give some of the main background bits to understanding HTML and CSS. It is far from comprehensive, but aims to be approachable and give enough background to understand more complex topics…later. 4 | 5 | ## Server and Browser 6 | 7 | A very basic overview: 8 | 9 | - The browser sends a **request** for a URL to a server. The URL includes a host, a path, and a query string, and the full request includes a set of HTTP headers. 10 | - The request is sent via the HTTP protocol, which sends basically a text file to the server. 11 | - The first part of the file is [**headers**](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields), which have some metadata about the request. 12 | - This includes information about the browser, timestamps, whether it is a GET, POST, or other request, the format the request expects, etc. 13 | - After a blank line, the rest of the file is any **body** of the request that might exist. 14 | - The **response** is sent by the server in much the same format, with the **body** section containing the HTML page or image data or whatever. 15 | - Note that there is no **necessary** correlation between files on disk and the URL. In other words, `http://example.com/important_file.html` could actually retrieve a file on disk called `/stuff/not_important.html`. Further, there may not even be a file on disk that represents the HTML, if you content is being dynamically generated. It's all up to how the HTTP server is configured! 16 | 17 | Example request/response (from [Wikipedia](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Example_session)) 18 | 19 | ### Request 20 | 21 | ``` 22 | GET /index.html HTTP/1.1 23 | Host: www.example.com 24 | ``` 25 | 26 | ### Response 27 | 28 | ``` 29 | HTTP/1.1 200 OK 30 | Date: Mon, 23 May 2005 22:38:34 GMT 31 | Content-Type: text/html; charset=UTF-8 32 | Content-Encoding: UTF-8 33 | Content-Length: 138 34 | Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT 35 | Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux) 36 | ETag: "3f80f-1b6-3e1cb03b" 37 | Accept-Ranges: bytes 38 | Connection: close 39 | 40 | 41 | 42 | An Example Page 43 | 44 | 45 | Hello World, this is a very simple HTML document. 46 | 47 | 48 | ``` 49 | 50 | Browsers will make further requests depending on the content of the page, but all requests take this basic format. (Well, WebSockets and HTTP 2 change that, but that's a different discussion.) 51 | 52 | ### Miscellaneous Notes 53 | 54 | - Browsers typically limit the number of requests to a single domain they will make at once…perhaps the limit is currently 8 or 32? 55 | - You can see the request/response cycle in the browser's dev tools. 56 | 57 | 58 | ## Tags (HTML) 59 | 60 | ### Theory 61 | 62 | - Used to indicate structure or meaning or "semantics" of a document. (so it's not just a flow of words) 63 | - Browsers give default styles to tags, but everything can be overriden. 64 | - (You'll want to use a CSS reset to normalize the browser's default styles.) 65 | - As much as possible, don't add tags just to change the appearance if it doesn't change the meaning. 66 | - [Mozilla has a nice reference of all the available tags.](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) 67 | 68 | #### Why "Meaning of the document"? 69 | 70 | Imagine you have some text. Using this section as an example, the raw text might look like this (abbreviated): 71 | 72 | ``` 73 | Tags (HTML) 74 | 75 | Theory 76 | 77 | Used to indicate… 78 | 79 | Practice 80 | 81 | Tags have parent-children relationship… 82 | ``` 83 | 84 | It's pretty difficult to navigate what those different bits of text are doing. How is it organized? If you were writing by hand, you might use larger and smaller writing, underlining, or different colors to communicate the organization and meaning. If using a word processor, you'd probably use some formatting features. If you only had plain-text, you might use something like Markdown: 85 | 86 | ``` 87 | # Tags (HTML) 88 | 89 | ## Theory 90 | 91 | - Used to indicate… 92 | 93 | ## Practice 94 | 95 | - Tags have parent-children relationship… 96 | ``` 97 | 98 | HTML is just another method of trying to communicate that structure, though primarily for **computer** consumption rather tha human consumption. A web browser takes that *meaning* and uses its default styles to show it to the user in a way that makes sense to humans. 99 | 100 | ``` 101 |

Tags (HTML)

102 | 103 | 104 | 105 | 108 | 109 |

Practice

110 | 111 | 114 | ``` 115 | 116 | ### Practice 117 | 118 | - Tags have **parent-children relationship**, and structure something like a family tree. 119 | - This relationship matters! Some tags cannot be children of other tags, and tags will frequently depend on their parent for some attributes of appearance or behavior. 120 | - Tags may come in **open-close pairs** that surround content `

text

` or be "self-closing" ``. While the HTML spec is not strict, I'd recommend **closing all tags**, either with a closing tag or by self-closing. 121 | - A few tags cannot have any content, such as the `` tag. 122 | - Tags can have **attributes** that can alter the default functionality of the tag or provide further context (i.e. `

` might indicate how important the paragraph is). 123 | - Attributes live inside the angle brackets after the tag name, with a label, an equals sign, and a value. 124 | - Some true/false attributes *only* need the label of the attribute. 125 | - Values technically don't need quotes, but it's simpler. Double or single is fine. 126 | - **Text** usually just shows up. It *should* probably be wrapped inside a tag, but doesn't have to be. 127 | - Spaces are collapsed—HTML enforces single spaces between words and sentences. 128 | - Use [HTML entities](https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references) for `<` (`<`) or `>` (`>`). 129 | - Browsers are (somewhat unfortunately) very forgiving and will try guess what tags you *meant* to have. Validation tools are recommended, especially ones built right in to your editor. 130 | 131 | ### Default Styles 132 | 133 | It isn't true for every tag (with the form elements being the most notable exception), but it is often true that the only difference between one tag and another is the default styling that the browser provides. 134 | 135 | (You'll likely want to include [Normalize.css](https://necolas.github.io/normalize.css/) to try make the browser default styles match across browsers. Bootstrap already includes this by default.) 136 | 137 | ### Browser Development Tools 138 | 139 | While all major browser include quality developer's tools, I will focus on [Chrome's DevTools](https://developers.google.com/web/tools/chrome-devtools/). Each browser's tools has their own strengths and weaknesses, and it isn't too uncommon to use more than one set when debugging certain issues. 140 | 141 | - Right-click on a page element and choose "Inspect Element". This will open the dev tools in most browsers, and focus that particular element in the element tree. 142 | - This is a live-updating representation of the HTML on your page, including any changes that JavaScript has made. 143 | - You can see the tree structure of the HTML DOM. 144 | - You can highlight any given element to see information about the CSS rules applied to that node, JavaScript event listeners, and more. 145 | - You can also live-edit the page—though of course your edits don't get saved. (Well, if you are working on something you have access to, there is theoretically a way for the changes to get saved…but I've never set that up.) 146 | - Get applied style information. 147 | - When you have an element focused in the Elements pane, you can look at the currently applied styles. 148 | - This shows **all** styles, organized with the most specific ones at the top, from any location that applies to this element, including the browser's default "user agent stylesheet". 149 | - There is also a graphic showing a bit of the box model, the margin, border, and padding applied to the element. 150 | - Get computed style information. 151 | - Sometimes, even when you see all the applied styles, you just want to know what the **end result** of applying all those styles was. That's what the "Computed" tab is for. 152 | - There is sometimes a disclosure triangle to the left of the properties, allowing you to trace back which CSS rules were used to make this computation. 153 | - [Lots more in the Chrome documentation](https://developer.chrome.com/devtools/docs/elements-styles). 154 | 155 | ### Useful `` Tags 156 | 157 | Note that the `` tag is has CSS `display: none` by default…but even that can be overridden! 158 | 159 | - `` is required 160 | - `<script>` is used for loading external JavaScript files…but, you probably want to put this **after** the closing `</body>` tag. Otherwise, your script will run **before** all the HTML is rendered on the screen. 161 | - `<link>` is used to pull in external CSS stylesheets. 162 | - There are lots of `<meta>` tag options that you can use for various extra indications to the browser, such as the character encoding (if not in the HTTP headers) or mobile device indications or favicons, etc. 163 | 164 | ## Selectors (CSS) 165 | 166 | The selector points to the HTML element you want to style. CSS selectors are used to "find" (or select) HTML elements based on their element name, id, class, attribute, and more. 167 | 168 | ### Element/type selectors 169 | The element selector selects elements based on the element name. For instance, a CSS rule like the following: 170 | 171 | ``` 172 | h1 { 173 | color: red; 174 | } 175 | ``` 176 | 177 | would style all the `<h1>` tags in the document red. 178 | 179 | ### ID Selectors 180 | The ID selector uses the id attribute of an HTML element to select a specific element. 181 | 182 | ``` 183 | #home-content { 184 | color: red; 185 | } 186 | ``` 187 | 188 | would style `<p id="home-content">red</p>` red, but not `<p id="content">blue</p>`. 189 | 190 | In practice, I've found that class selectors can do everything an ID selector can do, but are not limited to the one-unique-ID-per-page that ID selectors are. 191 | 192 | ### Class Selectors 193 | 194 | The class selector selects elements with a specific class attribute. Since an element can have many classes, the class selector only looks for a single class attribute. (Note that you can combine selectors…see below.) 195 | 196 | ``` 197 | .red { 198 | color: red; 199 | } 200 | ``` 201 | 202 | Would style `<p class="red yellow"></p>` and `<div class="red"></div>`, but not `<div id="red"></div>`. 203 | 204 | ### Combining Selectors 205 | 206 | You can combine selectors. For instance, a selector of `p#id.classone.classtwo` would only apply to `<p>` tags with an ID of `id` and **both** `classone` and `classtwo` in the list of classes. 207 | 208 | ### Group Selectors 209 | 210 | Sometimes, you want the same styling to apply to a group of selectors. Use a comma to separate the selectors before the declaration block. 211 | 212 | ``` 213 | h1, h2, h3 { 214 | color: blue; 215 | } 216 | ``` 217 | 218 | ### Universal Selector 219 | 220 | You can select **every** tag with `*`. Used rarely due to inheritance. 221 | 222 | ### Descendant Selectors 223 | 224 | Putting a space between selectors means that the second tag must be a child, grand-child, great-grant-child, etc. of the first. 225 | 226 | For instance, `.content p` would select `p` tags somewhere inside a tag with a `content` class, but not elsewhere. 227 | 228 | Descendant selectors tend to be heavily used. 229 | 230 | ### Attribute Selectors 231 | 232 | Attribute selectors allow you to pick an element based on its attribute. For instance, to style all `<input type="text" />` tags, you could use the rule `input[type="text]`. 233 | 234 | ### Other Selectors 235 | 236 | There are selectors like `:hover`, etc., that you can add to a selector to let a style apply only when the mouse is over the element. 237 | 238 | CSS also includes adjacent sibling selectors (`A + B`), general sibling selectors (`A ~ B`), and child selectors (`A > B`), but I've used those less. (With the exception of child selectors?) 239 | 240 | There are even pseudo-elements, like `::after` and `::before`, but those are outside the scope of this tutorial. 241 | 242 | ### References 243 | 244 | [Mozilla's MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference#Selectors) has some good information on selectors, as well as does [jQuery](https://api.jquery.com/category/selectors/). Be aware that the jQuery list name contain a few options that are not available in CSS or just not widely supported in browsers yet. 245 | 246 | ## Styles (CSS) 247 | 248 | ## Inheritance (CSS) 249 | 250 | Most text properties (font, size, etc.) get inherited, but most other properties do not. Look up the CSS property (or just try it!) to find out for sure. 251 | 252 | ## Cascading—which rule takes precedence if many apply (CSS) 253 | 254 | - Top to bottom. 255 | - The more "specific" the selector (i.e. adding up points) 256 | - Tags worth 1 point 257 | - Classes worth 10 points 258 | - IDs worth 100 points 259 | - inline styles worth 1000 points 260 | 261 | ## Units (CSS) 262 | 263 | - **percentages**: based on width of parent element (even when top and bottom!) 264 | 265 | ## Box Model 266 | 267 | - content, padding, border, margin 268 | - collapsing margins (two top-to-bottom margins next to each other, takes largest) 269 | - negative margins 270 | - 271 | - **block** 272 | - break before and after 273 | - full width of viewport (not sure how exactly specified: 100%? 100vw? other?) 274 | - height via CSS **or** content 275 | - `<div />` by default, though can change 276 | - **inline** 277 | - no break, same line as content before & after 278 | - left/right padding, left/right margins 279 | - `<span />` by default, though can change 280 | - **inline-block** 281 | - like `inline`, but accepts top/bottom margin, top/bottom padding, height 282 | 283 | 284 | ## Tools 285 | 286 | If you don't have a web server set up, you can use the following Python snippet to start one in the current directory (**don't use this in production!**): 287 | 288 | ``` 289 | python -m SimpleHTTPServer 290 | ``` 291 | 292 | And then access your pages at [http://localhost:8000](http://localhost:8000). -------------------------------------------------------------------------------- /JavaScript/EqualityOfObjectsAndArraysInJavaScript.markdown: -------------------------------------------------------------------------------- 1 | # Equality of Objects and Arrays in JavaScript 2 | 3 | Related to the question of [reference and value in calling functions](./PassByReferenceandValue.markdown) is the question of equality: when are two values `===` to each other? (I'm restricting myself to `===` in JavaScript to simplify things a bit; [you can read up the rules if you want](https://dorey.github.io/JavaScript-Equality-Table/).) 4 | 5 | ```javascript 6 | 1 === 1; // true 7 | [1] === [1]; // false 8 | {a: 1} === {a: 1}; // false 9 | ``` 10 | 11 | Why is this? 12 | 13 | In JavaScript, "primitive" values are compared "by value". That means that strings, numbers, and booleans are all compared by the value that they contain, as in line 1 above. 14 | 15 | ## `===` on Objects and Arrays 16 | 17 | On the other hand, objects and arrays (basically everything else in JavaScript) are compared "by reference." That means that the computer doesn't look at all in the values *contained* in the array, but instead simply looks at the memory location that the data is stored in. If the memory location is the same, they are equal, but if the memory location is different, they are *not* equal. While you know that two objects must be equal if they point to the same memory location, the inverse isn't true at all. 18 | 19 | In other words, since we created **two** separate arrays in line 2 above, they point to two separate memory locations, and so are not equal. 20 | 21 | ## Multiple Names for the Same Data 22 | 23 | This is also confusing in other ways. For instance: 24 | 25 | ```javascript 26 | const a = [1]; 27 | const b = a; 28 | a.push(2); 29 | a === b; // true 30 | console.log(a, b); // [1, 2], [1, 2] 31 | ``` 32 | 33 | Even though it looks like we only `push`ed on to `a`, both `a` and `b` point to the same memory location and are two names for the same thing. So they are `===` equal, and will always contain the same information. 34 | 35 | ## How do I copy an object or array? 36 | 37 | It depends. A couple ideas come to mind: 38 | 39 | - `_.clone` will create a shallow clone. 40 | - `_.cloneDeep` will create a deep clone. 41 | - `for` loops can work (shallow). 42 | - `.map` and friends (on arrays) always returns a new array (shallow). 43 | - `JSON.parse(JSON.stringify(x))` can work in a pinch. A deep clone, but is limited to JSON data structures, and I've no idea how the performance compares. But it is easy. 44 | 45 | ### What's with "deep" and "shallow" clones? 46 | 47 | A "deep" clone is what you'd expect: a complete copy without anything shared with the original data structure. However, this can be slower than a shallow clone for nested data structures. 48 | 49 | A "shallow" clone only clones the first level deep of the data structure. This means that some of the values in the object (or array) might still be shared. A simple example: 50 | 51 | ```javascript 52 | const a = [[1]]; 53 | const b = _.clone(a); 54 | a[0].push(2); 55 | console.log(a, b); // [[1, 2]], [[1, 2]] 56 | ``` 57 | 58 | The first element of `a`, which is *also* an array, is shared, so pushing on to it also affects `b`. A deep clone would keep them entirely separate. 59 | 60 | ```javascript 61 | const a = [[1]]; 62 | const b = _.cloneDeep(a); 63 | a[0].push(2); 64 | console.log(a, b); // [[1, 2]], [[1]] 65 | ``` 66 | 67 | ## How do I see if arrays or objects are equal? 68 | 69 | Just as with the clones, there are "deep" and "shallow" variations. Do you care only about the top level? Do you care about every level deep? For that matter, do you care if the elements in an array are in the same order? Do you care about sets or other JavaScript data structures? 70 | 71 | All that said, a few places to get started: 72 | 73 | - `_.isEqual` will do a deep comparison of a lot of JavaScript data structures. 74 | - A `for…in` or `for…of` loop can do a quick shallow comparison. 75 | - `JSON.stringify(x) === JSON.stringify(y)` can be handy if you don't care about the performance and need a quick test while debugging. 76 | - `Immutable.is` works well for Immutable.js data structures (deep, but I'm not sure of the performance characteristics). 77 | 78 | As with the clone, performance depends on how much data you are comparing. 79 | 80 | Here's an example of a loop to compare two objects shallowly (roughly from [Facebook's implementation](https://github.com/facebook/fbjs/blob/4369c7dfeb1ab0de27feb3e9245f599c8edd6a5c/packages/fbjs/src/core/shallowEqual.js#L34-L67): 81 | 82 | ```javascript 83 | function shallowEqual(objA, objB) { 84 | if (is(objA, objB)) { 85 | return true; 86 | } 87 | 88 | if (typeof objA !== 'object' || objA === null || 89 | typeof objB !== 'object' || objB === null) { 90 | return false; 91 | } 92 | 93 | const keysA = Object.keys(objA); 94 | const keysB = Object.keys(objB); 95 | 96 | if (keysA.length !== keysB.length) { 97 | return false; 98 | } 99 | 100 | // Test for A's keys different from B. 101 | for (let i = 0; i < keysA.length; i++) { 102 | if ( 103 | !hasOwnProperty.call(objB, keysA[i]) || 104 | !(objA[keysA[i]] === objB[keysA[i]]) 105 | ) { 106 | return false; 107 | } 108 | } 109 | 110 | return true; 111 | } 112 | ``` 113 | 114 | -------------------------------------------------------------------------------- /JavaScript/IntroductoryJSArrayObject.markdown: -------------------------------------------------------------------------------- 1 | # Array Object Exercises (JavaScript) 2 | 3 | ## Questions 4 | 5 | 1. If you have an array `var a = [ 0, 1, 2, 3, 4 ];`, how do you extract the value 3 from the array? 6 | 7 | 2. If you have the following object, how do you extract the value 3 from the object? 8 | 9 | ``` 10 | var a = { 11 | "zero": 0, 12 | "one": 1, 13 | "two": 2, 14 | "three": 3, 15 | "four": 4 16 | }; 17 | ``` 18 | 19 | 3. If you have the following array, how do you extract the value 3 from the array? 20 | 21 | ``` 22 | var a = [ 23 | [ 24 | 0, 25 | 1 26 | ], 27 | [ 28 | 2, 29 | [ 30 | 3 31 | ] 32 | ] 33 | ]; 34 | ``` 35 | 36 | 4. If you have the following object, how do you extract the value 3 from the object? 37 | 38 | ``` 39 | var a = { 40 | "a": { 41 | "b": 0, 42 | "c": 1 43 | }, 44 | "b": { 45 | "e": 2, 46 | "o": { 47 | "b": 3 48 | } 49 | } 50 | }; 51 | ``` 52 | 53 | 5. Create a new array with each comma-separated value as its own array element from the string `var a = "a,b,c,d,e,f"`. 54 | 55 | 6. With the result array from `5`, create a new object where each element is *both* key *and* value. In other words, the result should be: 56 | 57 | ``` 58 | { 59 | "a": "a", 60 | "b": "b", 61 | "c": "c", 62 | "d": "d", 63 | "e": "e" 64 | } 65 | ``` 66 | 67 | 7. You have two objects like the following. One contains field labels, the other contains field values. Write a program to output the third object. 68 | 69 | ``` 70 | var keys = { 71 | "field1": "first", 72 | "field2": "second", 73 | "field3": "third" 74 | }; 75 | var values = { 76 | "field1value": "dinosaur", 77 | "field2value": "pig", 78 | "field3value": "platypus" 79 | }; 80 | 81 | // want to output 82 | var keysAndValues = { 83 | "first": "dinosaur", 84 | "second": "pig", 85 | "third": "platypus" 86 | }; 87 | ``` 88 | 89 | 8. You have an array of transactions, each of which has a debit and credit amount. Find the absolute value of the transaction amount (i.e. `abs( debit - credit )`) and add it as a new `key=>value` pair to each transaction. 90 | 91 | ``` 92 | var transactions = [ { 93 | "debit": 2, 94 | "credit": 3 95 | }, { 96 | "debit": 15, 97 | "credit": 14 98 | } ]; 99 | 100 | // outputs 101 | transactions = [ { 102 | "debit": 2, 103 | "credit": 3, 104 | "amount": 1 105 | }, { 106 | "debit": 15, 107 | "credit": 14, 108 | "amount": 1 109 | } ]; 110 | ``` 111 | 112 | 9. Find the sum of this array of numbers `var a = [ 0, 1, 2, 3, 4, 5, 6 ];`. 113 | 114 | ## Sample Answers (others may be correct :-D) 115 | 116 | 1. `a[ 3 ];` 117 | 118 | 2. `a.three;` 119 | 120 | 3. `a[1][1][0];` 121 | 122 | 4. `a.b.o.b;` 123 | 124 | 5. `a = a.split( "," );` 125 | 126 | 6. Samples: 127 | 128 | ``` 129 | var b = {}; 130 | a.forEach( function( value, index ) { 131 | b[ value ] = value; 132 | } ); 133 | ``` 134 | 135 | **or** 136 | 137 | ``` 138 | var b = {}; 139 | for ( var i = 0; i < a.length; i++ ) { 140 | b[ a[ i ] ] = a[ i ]; 141 | } 142 | ``` 143 | 144 | 7. Samples: 145 | 146 | ``` 147 | keysAndValues = {}; 148 | keysAndValues[ keys.field1 ] = values.field1value; 149 | keysAndValues[ keys.field2 ] = values.field2value; 150 | keysAndValues[ keys.field3 ] = values.field3value; 151 | ``` 152 | 153 | **or** 154 | 155 | ``` 156 | var keysAndValues = {}; 157 | [1, 2, 3].forEach(function(number) { 158 | var key = keys["field" + number]; 159 | var value = values["field" + number + "value"]; 160 | keysAndValues[key] = value; 161 | }); 162 | ``` 163 | 164 | 8. Samples 165 | 166 | ``` 167 | transactions.map( function( transaction ) { 168 | return ( transaction.amount = Math.abs( transaction.debit - transaction.credit ) ); 169 | } ); 170 | 171 | ``` 172 | 173 | **or** 174 | 175 | ``` 176 | transactions.forEach( function( transaction ) { 177 | transaction.amount = Math.abs( transaction.debit - transaction.credit ); 178 | } ); 179 | ``` 180 | 181 | 9. Samples: 182 | 183 | ``` 184 | var sum = a.reduce( function( x, y ) { 185 | return x + y; 186 | }, 0 ); 187 | ``` 188 | 189 | **or** 190 | 191 | ``` 192 | var sum = 0; 193 | a.forEach( function( value ) { 194 | sum += value; 195 | } ); 196 | ``` 197 | 198 | **or** 199 | 200 | ``` 201 | var sum = 0; 202 | for ( var i = 0; i < a.length; i++ ) { 203 | sum += a[ i ]; 204 | } 205 | ``` 206 | -------------------------------------------------------------------------------- /JavaScript/PassByReferenceandValue.markdown: -------------------------------------------------------------------------------- 1 | ## Pass by Reference and Value 2 | 3 | > **Note**: The examples here are in JavaScript, but can affect many other languages such as PHP. 4 | 5 | It can be really easy to get confusing results when your functions change ("mutate") the objects that you pass in to them. 6 | 7 | For instance, let's say that you want to write a function that takes in some data of the following form: 8 | 9 | ```javascript 10 | const data = [{ a: 1, b: 2 }, { a: 3, b: 4 }]; 11 | ``` 12 | 13 | It will take each object in the array, calculate the total of its values, and add that total onto the object. In other words, it should return an array like: 14 | 15 | ```javascript 16 | const desired_result = [{ a: 1, b: 2, total: 3 }, { a: 3, b: 4, total: 7 }]; 17 | ``` 18 | 19 | Seems straightforward. 20 | 21 | ```javascript 22 | function totalValues(arr) { 23 | let new_array = []; 24 | for (const obj of arr) { 25 | const values = Object.values(obj); // [1,2] or [3,4] 26 | let total = 0; 27 | for (const el of values) { 28 | total += el; 29 | } 30 | obj.total = total; 31 | new_array.push(obj); 32 | } 33 | return new_array; 34 | } 35 | ``` 36 | 37 | Let's see if it works! 38 | 39 | ```javascript 40 | const totals = totalValues(data); 41 | console.log(JSON.stringify(totals) === JSON.stringify(desired_result)); // true 42 | console.log(totals); // "[{a:1, b:2, total:3}, {a:3, b:4, total:7}]" 43 | ``` 44 | 45 | Looks like it worked perfectly! Hooray! 46 | 47 | But there **is** a lurking problem. What happens if we run the same thing again? 48 | 49 | ```javascript 50 | const totals2 = totalValues(data); 51 | JSON.stringify(totals2) === JSON.stringify(desired_result); // false 52 | ``` 53 | 54 | False?!?! Why did it fail? Let's look more closely… 55 | 56 | ```javascript 57 | console.log(totals2); // "[{a:1, b:2, total:6}, {a:3, b:4, total:14}]" 58 | ``` 59 | 60 | Where are those totals coming from? 61 | 62 | Aaargh!!!! 63 | 64 | What's my data again? 65 | 66 | ```javascript 67 | console.log(data); // "[{a:1, b:2, total:6},{a:3, b:4, total:14}]" 68 | ``` 69 | 70 | Hey! Who put `totals` in my data? 71 | 72 | And therein lies the problem: since `totalValues` **changes** the original objects in `data`, every time we run total, it uses the **most recent** version of `data`, rather than the one originally specified. **Even though we are carefully creating a new array to return!** 73 | 74 | This is where immutable data structures really shine—this problem would not happen. But how do you fix this in plain ol' JavaScript? 75 | 76 | Probably something like: 77 | 78 | ```javascript 79 | new_array.push({ 80 | ...obj, 81 | total 82 | }); 83 | ``` 84 | 85 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 David Alan Hjelle 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /PHP/Introductory Array Exercises.markdown: -------------------------------------------------------------------------------- 1 | # Array Exercises (PHP) 2 | 3 | ## Questions 4 | 5 | 1. If you have an array `$a = array( 0, 1, 2, 3, 4 );`, how do you extract the value 3 from the array? 6 | 7 | 2. If you have an array `$a = array( "zero"=>0, "one"=>1, "two"=>2, "three"=>3, "four"=>4 );`, how do you extract the value 3 from the array? 8 | 9 | 3. If you have the following array, how do you extract the value 3 from the array? 10 | 11 | ``` 12 | $a = array( 13 | array( 14 | 0, 15 | 1 16 | ), 17 | array( 18 | 2, 19 | array( 20 | 3 21 | ) 22 | ) 23 | ); 24 | ``` 25 | 26 | 4. If you have the following array, how do you extract the value 3 from the array? 27 | 28 | ``` 29 | $a = array( 30 | "a"=>array( 31 | "b"=>0, 32 | "c=>1 33 | ), 34 | "b"=>array( 35 | "e"=>2, 36 | "o"=>array( 37 | "b"=>3 38 | ) 39 | ) 40 | ); 41 | ``` 42 | 43 | 5. Create a new array with each comma-separated value as its own array element from the string `$a = "a,b,c,d,e,f"`. 44 | 45 | 6. With the result array from `5`, create a new array where each element is *both* key *and* value. In other words, the result should be: 46 | 47 | ``` 48 | array( 49 | "a"=>"a", 50 | "b"=>"b", 51 | "c"=>"c", 52 | "d"=>"d", 53 | "e"=>"e" 54 | ) 55 | ``` 56 | 57 | 7. You have two arrays like the following. One contains field labels, the other contains field values. Write a program to output the third array. 58 | 59 | ``` 60 | $keys = array( 61 | "field1"=>"first", 62 | "field2"=>"second", 63 | "field3"=>"third" 64 | ); 65 | $values = array( 66 | "field1value"=>"dinosaur", 67 | "field2value"=>"pig", 68 | "field3value"=>"platypus" 69 | ); 70 | // want to output 71 | $keysAndValues = array( 72 | "first"=>"dinosaur", 73 | "second"=>"pig", 74 | "third"=>"platypus" 75 | ); 76 | ``` 77 | 78 | 8. You have an array of transactions, each of which has a debit and credit amount. Find the absolute value of the transaction amount (i.e. `abs( debit - credit )`) and add it as a new `key=>value` pair to each transaction. 79 | 80 | ``` 81 | $transactions = array( 82 | array( 83 | "debit"=>2, 84 | "credit"=>3 85 | ), 86 | array( 87 | "debit"=>15, 88 | "credit"=>14 89 | ) 90 | ); 91 | // outputs 92 | $transactions = array( 93 | array( 94 | "debit"=>2, 95 | "credit"=>3, 96 | "amount"=>1 97 | ), 98 | array( 99 | "debit"=>15, 100 | "credit"=>14, 101 | "amount"=>1 102 | ) 103 | ); 104 | ``` 105 | 106 | 9. Find the sum of this array of numbers `$a = array( 0, 1, 2, 3, 4, 5, 6 );`. 107 | 108 | ## Sample Answers (others may be correct :-D) 109 | 110 | 1. `$a[ 3 ];` 111 | 112 | 2. `$a[ "three" ];` 113 | 114 | 3. `$a[ 1 ][ 1 ][ 0 ];` 115 | 116 | 4. `$a[ "b" ][ "o" ][ "b" ];` 117 | 118 | 5. `$a = explode( ",", $a );` 119 | 120 | 6. Samples: 121 | 122 | ``` 123 | $new_array = array(); 124 | foreach( $a as $element ) { 125 | $new_array[ $element ] = $element; 126 | } 127 | ``` 128 | 129 | **or** 130 | 131 | `array_combine( $a, $a );` 132 | 133 | How would you write your own `array_combine` function? 134 | 135 | 7. Samples: 136 | 137 | ``` 138 | // can you spot the bug? 139 | $keysAndValues = array(); 140 | $keysAndValues[ $keys[ "field1" ] ] = $values[ "field1value" ]; 141 | $keysAndValues[ $keys[ "field2" ] ] = $values[ "field2value" ]; 142 | $keysAndValues[ $keys[ "field3" ] ] = $values[ "field2value" ]; 143 | ``` 144 | 145 | **or** 146 | 147 | ``` 148 | $keysAndValues = array(); 149 | foreach( array( 1, 2, 3 ) as $index ) { 150 | $keysAndValues[ $keys[ "field$index" ] ] = $values[ "field" . $index . "value" ]; 151 | } 152 | ``` 153 | 154 | **or** 155 | 156 | ``` 157 | $keysAndValues = array_combine( array_values( $keys ), array_values( $values ) ); 158 | ``` 159 | 160 | 8. Samples 161 | 162 | ``` 163 | $new_transactions = array(); 164 | foreach( $transactions as $transaction ) { 165 | $new_transaction = $transaction; 166 | $new_transaction[ "amount" ] = abs( $transaction[ "debit" ] - $transaction[ "credit" ] ); 167 | $new_transactions[] = $new_transaction; 168 | } 169 | $transactions = $new_transactions; 170 | ``` 171 | 172 | **or** 173 | 174 | ``` 175 | $transactions = array_map( function( $transaction ) { 176 | $transaction[ "amount" ] = abs( $transaction[ "debit" ] - $transaction[ "credit" ] ); 177 | return $transaction; 178 | }, $transactions ); 179 | ``` 180 | 181 | 9. Samples: 182 | 183 | ``` 184 | $sum = 0; 185 | foreach( $a as $element ) { 186 | $sum += $element; 187 | } 188 | ``` 189 | 190 | **or** 191 | 192 | ``` 193 | $sum = array_reduce( $a, function( $partial_sum, $element ) { 194 | return $partial_sum + $element; 195 | }, 0 ); 196 | ``` 197 | 198 | **or** 199 | 200 | ``` 201 | $sum = array_sum( $a ); 202 | ``` 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Programming-Worksheets 2 | ====================== 3 | 4 | Simple Programming Worksheets for Learning 5 | 6 | 7 | Wrote up the first one as a internal training tool. We may add more (and in other languages) as need permits. 8 | 9 | Contributions/corrections very welcome! 10 | -------------------------------------------------------------------------------- /React.js/IntroductoryReact.markdown: -------------------------------------------------------------------------------- 1 | # React Bit-by-Bit: An Introduction for Beginners 2 | 3 | This will provide a gradual implementation of the 'todo' application on [React's website](https://facebook.github.io/react/) (or a close approximation). 4 | 5 | ## Boilerplate 6 | 7 | If you are just starting, I'd suggest using [JSBin](http://jsbin.com/tawaqaviyo/1/edit?js,console,output) to play around; you can learn React without having to install anything locally. 8 | 9 | If you want to develop locally, this assumes you have an `index.html` that includes both React and `index.js` (which we'll mention in a moment) and a `index.jsx` or similar that is getting compiled to the `index.js` file previously mentioned. We'll technically be using `browserify`, but `webpack` or similar should work fine. 10 | 11 | We don't discuss the preparation of those files in this tutorial. 12 | 13 | ## Simplest React Application 14 | 15 | To render HTML to the screen, use `React.render`: 16 | 17 | ```JavaScript 18 | var React = require('react'); // we'll assume this line is present for all future code snippets; it is ONLY needed if you are using the browserify or webpack setup 19 | 20 | React.render( 21 | <p>Hello, world!</p>, 22 | document.body 23 | ); 24 | ``` 25 | 26 | `React.render` takes the "JSX" (an HTML-like language that lives in your JavaScript) that you pass it as the *first* parameter, and fills the HTML element you give it as the *second* parameter with the result. In this case, putting the `<p>` inside the `<body>` tag on your page. (The differences between HTML and JSX are [documented on the React site](https://facebook.github.io/react/docs/jsx-gotchas.html).) 27 | 28 | JSX can be assigned to variables.† In other words, we can refactor the above example to: 29 | 30 | ```JavaScript 31 | var contents = <p>Hello, world!</p>; 32 | 33 | React.render( 34 | contents, 35 | document.body 36 | ); 37 | ``` 38 | 39 | You can nest JSX tags, just like in HTML. 40 | 41 | ```JavaScript 42 | var contents = <p>Hello, <small>small</small> world!</p>; 43 | 44 | React.render( 45 | contents, 46 | document.body 47 | ); 48 | ``` 49 | 50 | † In the background, each JSX tag actually corresponds to a function, but you mostly don't need to worry about that. 51 | 52 | **Exercise 1**: Try make a few variations of HTML tags of your own display using JSX and React. 53 | 54 | ## Combining JSX and JavaScript 55 | 56 | You can grab JavaScript values and place them in your JSX. This is done by surrounding the JavaScript expression in {}. For instance: 57 | 58 | ```JavaScript 59 | var name = 'Samuel'; // Regular JavaScript variable 60 | var contents = <p>Hello, <b>{name}</b>!</p>; // drop the variable into your HTML using '{}' 61 | 62 | React.render( 63 | contents, 64 | document.body 65 | ); 66 | ``` 67 | 68 | The JavaScript values can be either regular JavaScript expressions or other React elements. 69 | 70 | ```JavaScript 71 | var name = 'Bob'; 72 | var bold_name = <b>{name + ' - the man, the myth, the legend'}</b>; 73 | var contents = <p>It's time to meet…{bold_name}.</p>; 74 | 75 | React.render( 76 | contents, 77 | document.body 78 | ); 79 | ``` 80 | 81 | You can use JavaScript expressions as attribute values in the JSX tags. 82 | 83 | ```JavaScript 84 | var name = 'Samuel'; 85 | var contents = 86 | <p> 87 | <span>Name Box: </span> 88 | <input value={name} /> 89 | </p>; // You will not be able to edit the input field's contents in the browser when this renders. We will discuss that later. 90 | 91 | React.render( 92 | contents, 93 | document.body 94 | ); 95 | ``` 96 | 97 | **Note**: JSX always requires a single parent element with all other elements wrapped inside of it. So, for the above example, it wouldn't work to add another `<p>...</p>` to the beginning; you would need to wrap the whole thing in `<div>...</div>`, `<span>...</span>`, etc. 98 | 99 | ```JavaScript 100 | //WRONG 101 | var name = 'Samuel'; 102 | var contents = 103 | <p>Put your name below</p> 104 | <p> 105 | <span>Name Box: </span> 106 | <input value={name} /> 107 | </p>; 108 | 109 | //RIGHT 110 | var name = 'Samuel'; 111 | var contents = 112 | <div> 113 | <p>Put your name below.</p> 114 | <p> 115 | <span>Name Box: </span> 116 | <input value={name} /> 117 | </p> 118 | </div>; //Notice the opening <div> at the beginning of the contents variable and the closing </div> at the end of it. 119 | ``` 120 | 121 | **Exercise 2**: Render an unordered list `<ul>` of several items using JavaScript variables and JSX. 122 | 123 | ## Arrays in JSX 124 | 125 | In the last exercise, you probably noticed it was a bit of a pain to create multiple list items. Wouldn't it be nice if JSX would accept arrays? It turns out, it will. 126 | 127 | ```JavaScript 128 | var paragraphs = ['one', 'two', 'three']; 129 | paragraphs = paragraphs.map(function(paragraph) { 130 | return <p> 131 | {paragraph} 132 | </p>; 133 | }); 134 | var content = <div> 135 | {paragraphs} 136 | </div>; 137 | 138 | React.render( 139 | content, 140 | document.body 141 | ); 142 | ``` 143 | 144 | Why did we need the extra `<div>` tag to make `content`? Unfortunately, while JSX itself accepts arrays, `React.render` will only accept JSX components. This is usually not a problem in practice, but does require a container `<div>` in this instance. 145 | 146 | Now, strictly speaking, even though the above code renders the paragraphs just fine, you might notice a warning about 'unique "key" prop' in your console. (Or you might not.) This means that React wants each React component inside an array like this to have a `key` property that is unique amongst all array elements. Let's fix it: 147 | 148 | ```JavaScript 149 | var paragraphs = ['one', 'two', 'three']; 150 | paragraphs = paragraphs.map(function(paragraph, index) { 151 | return <p key={index}> 152 | {paragraph} 153 | </p>; 154 | }); 155 | var content = <div> 156 | {paragraphs} 157 | </div>; 158 | 159 | React.render( 160 | content, 161 | document.body 162 | ); 163 | ``` 164 | 165 | **Exercise 3**: Do exercise #2 again, except with arrays. Make sure you don't get React errors in your console! 166 | 167 | ## Embrace Modularity: Basic React Components 168 | 169 | Programming in a modular way—i.e. packaging bits of functionality into distinct components or modules—tends to make our code more eloquent, flexible and maintainable. 170 | 171 | So far, we've seen how JSX can be combined with all the logic ability of JavaScript to do some interesting things. It'd be nice now if we could package up pieces of JSX functionality into unique components. React lets us do this as well—basically allowing us to add our own unique HTML tags to the browser! 172 | 173 | For instance, let's package up the previous paragraphs into a React component. 174 | 175 | ```JavaScript 176 | var Paragraphs = React.createClass({ 177 | render: function() { 178 | var paragraphs = ['one', 'two', 'three']; 179 | paragraphs = paragraphs.map(function(paragraph, index) { 180 | return <p key={index}> 181 | {paragraph} 182 | </p>; 183 | }); 184 | return <div> 185 | {paragraphs} 186 | </div>; 187 | } 188 | }); 189 | 190 | React.render( 191 | <Paragraphs />, 192 | document.body 193 | ); 194 | ``` 195 | 196 | In this case, we've created a component called `Paragraphs` (traditionally starting with a capital letter) with the `React.createClass` function. This function accepts an object, with a single required key of `render`. The `render` key has to be a function that will `return` JSX. 197 | 198 | Once we create a component, we can use it in JSX directly, as if it was an HTML tag. 199 | 200 | So in the example above... 201 | First, we create the `Paragraphs` component with the `React.createClass` function. 202 | Next, in the `render` key of `createClass`, we use JavaScript and JSX to define our variables as we did previously. 203 | We then `return` the output we want for our `Paragraphs` component. 204 | Now we can call `<Paragraphs />` as a unique HTML tag whenever we need it. 205 | 206 | We can call our new `Paragraphs` component directly in `React.render`, or we can use it inside other components. 207 | 208 | ```JavaScript 209 | var Paragraphs = React.createClass({ 210 | render: function() { 211 | var paragraphs = ['one', 'two', 'three']; 212 | paragraphs = paragraphs.map(function(paragraph, index) { 213 | return <p key={index}> 214 | {paragraph} 215 | </p>; 216 | }); 217 | return <div> 218 | {paragraphs} 219 | </div>; 220 | } 221 | }); 222 | 223 | var MoreOfThem = React.createClass({ 224 | render: function() { 225 | return <div> 226 | <Paragraphs /> 227 | <Paragraphs /> 228 | <Paragraphs /> 229 | </div>; 230 | } 231 | }) 232 | 233 | React.render( 234 | <MoreOfThem />, 235 | document.body 236 | ); 237 | ``` 238 | 239 | Above, we're using our `Paragraphs` component inside of our new `MoreOfThem` component. In `MoreOfThem`, look at what's happening in the `render` key. We're returning the `Paragraphs` key three times, so when we call `MoreOfThem` in `React.render`, `Paragraphs` is repeated three times. 240 | 241 | If you are using a build tool like `browserify`, you can also stick your components in other files. 242 | 243 | ```JavaScript 244 | // paragraphs.jsx 245 | var React = require('react'); 246 | var Paragraphs = React.createClass({ 247 | render: function() { 248 | var paragraphs = ['one', 'two', 'three']; 249 | paragraphs = paragraphs.map(function(paragraph, index) { 250 | return <p key={index}> 251 | {paragraph} 252 | </p>; 253 | }); 254 | return <div> 255 | {paragraphs} 256 | </div>; 257 | } 258 | }); 259 | module.exports = Paragraphs; 260 | ``` 261 | 262 | The `module.exports` assignment makes your `Paragraphs` component available in other JSX files when you require your `paragraphs.jsx` file. 263 | 264 | ```JavaScript 265 | // index.jsx 266 | var React = require('react'); 267 | var Paragraphs = require('./paragraphs.jsx'); 268 | React.render( 269 | <Paragraphs />, 270 | document.body 271 | ); 272 | ``` 273 | 274 | **Exercise 4**: Render your unordered list via a component. 275 | 276 | 277 | ## Interacting with Your Components: State 278 | 279 | This has been interesting so far, but there isn't yet much that we could do with React that wouldn't have been done in plain old HTML or in the various HTML templating languages. (And, to be fair, React is far from the only way of doing what we'll be doing here, either.) But we want to move beyond just rendering HTML tags and create a user interface that's *interactive*. Let's make a component with some interactivity! 280 | 281 | First, we need to introduce the concept of 'state'. State is a value that can change over time, and is local to the component. For instance, imagine that we have a `<Clock/>` component that displays an hour hand and a minute hand, representing the current time. The position of those hands would likely be state: they change over time, but no other component using the `<Clock/>` is likely to need or want to know that position. State allows us to keep such values local to a component. Keeping changing states local - set apart for a certain component - will help us program in a modular way. 282 | 283 | So how do we use state? See below and pay special attention to the `getInitialState` key. 284 | 285 | ```JavaScript 286 | var Stateful = React.createClass({ 287 | getInitialState: function() { 288 | return { 289 | backcolor: '#0000FF' 290 | }; 291 | }, 292 | render: function() { 293 | var divStyle = { 294 | backgroundColor: this.state.backcolor, 295 | color: '#FFFFFF' 296 | }; 297 | return <div style={divStyle}> 298 | Hello, world! 299 | </div>; 300 | } 301 | }); 302 | 303 | React.render( 304 | <Stateful />, 305 | document.body 306 | ); 307 | ``` 308 | 309 | First, notice that we added a second function to our React component as the value for `getInitialState`. If you provide this function (and you should if you are using state), you should return a single object. The keys correspond to the names of the state variables you'll use, and the values are their initial values (which can change later). In this case, we are setting the `backcolor` state variable to a CSS color of `#0000FF` (a bright blue). While we only have a single state variable in this example, you can have as many as you need. 310 | 311 | Second—a brief digression. As mentioned earlier, JSX allows us to put JavaScript values inside our JSX tags. In the case of CSS styles, it does something additional: it will accept a JavaScript object that will get converted to the appropriate CSS string. There is [React documentation](https://facebook.github.io/react/tips/inline-styles.html) on this sort of thing, but accept it for now that `backgroundColor` affects the background color of an HTML element, and `color` affects the *text* color of an element when they are passed to the `style` attribute of an HTML tag. 312 | 313 | Third, onward. So, in this case, we have an initial `state` with a `backcolor` of `#0000FF`. In the `render` function (or other functions we may create ourselves), we can access that `state` via `this.state.VARIABLE_NAME`—in this case, `this.state.backcolor`. We use `this.state.backcolor` to create a `divStyle` object, which we use to set the `style` of the div that we render. 314 | 315 | **BUT!** We still haven't made anything interactive? How can we do that? 316 | 317 | Before we change the state based on user interaction, let's explore how we can handle events initiated by the user. The basic mechanics are very similar to old-school HTML events: adding event handlers to our JSX tags. (And [React has documentation on the specifics of what events can be handled in JSX](https://facebook.github.io/react/docs/events.html).) So, for example, we can run a function when the mouse is clicked on our `<div/>`: 318 | 319 | ```JavaScript 320 | var Events = React.createClass({ 321 | clickHandler: function() { 322 | console.log('You got me!'); 323 | }, 324 | render: function() { 325 | return <div onClick={this.clickHandler}> 326 | Hello, world! 327 | </div>; 328 | } 329 | }); 330 | 331 | React.render( 332 | <Events />, 333 | document.body 334 | ); 335 | ``` 336 | 337 | In this case, we print to the `console` whenever the `<div/>` is clicked on. We attach an `onClick` event handler to the `<div>` JSX element, and that event handler is `this.clickHandler`, the `clickHandler` function we defined in the object given to `React.createClass`. The name of the handler function can be anything (clickHandler, stateChanger, userClick ... whatever you want). 338 | 339 | While the React documentation as a complete list of events that can be handled, consider for now `onClick`, `onMouseOver`, and `onMouseOut`. 340 | 341 | Let's recap. 342 | 1. We can create an initial, changeable state for our component by assigning a function to `getInitialState` (like `backcolor: '#0000FF'`). 343 | 2. We can use that state in our `render` with `this.state.VARIABLE` (which is `this.state.backcolor` in our example). 344 | 3. We can record what the user is doing with event handlers - `onClick`, `onMouseOver`, `onMouseOut` and such - and respond by calling functions. 345 | 346 | So how do we change our state based on user interaction? Glad you asked! Enter the puzzle piece that brings all this together... `this.setState()`. 347 | 348 | ```JavaScript 349 | var Stateful = React.createClass({ 350 | getInitialState: function() { 351 | return { 352 | backcolor: '#0000FF' //blue 353 | }; 354 | }, 355 | clickHandler: function() { 356 | this.setState({ // Here's where the interactivity comes to life and the backcolor is changed. 357 | backcolor: '#DD3131' 358 | }); 359 | }, 360 | render: function() { 361 | var divStyle = { 362 | backgroundColor: this.state.backcolor, //this.state is empty initially {}. it grabs getInitialState setting backcolor to blue above. So now this.state has {backcolor: '#00000FF'}. The render function always starts with the getInitialState to see what the component is made of. It now sets the background color to the backcolor. 363 | color: '#FFFFFF' // It then adds the color (White) for the text to the divStyle. 364 | }; 365 | return <div style={divStyle} onClick={this.clickHandler}> // This executes the clickHandler function above to change the color on the backcolor. It also attaches the click handler on the first run through the render so the user can interact with it. 366 | Hello, world! 367 | </div>; 368 | } 369 | }); 370 | 371 | React.render( 372 | <Stateful />, 373 | document.body 374 | ); 375 | ``` 376 | 377 | When `this.setState` is called by your `clickHandler` function, you pass an object whose keys are the state variables that you want to change, and the values are the corresponding new values you want to see in the browser. You can set as many or as few state variables as necessary for to make the interactive changes you want in your application. 378 | 379 | When you call `this.setState`, it tells React: 'Hey, I have some new state. Can you please re-render me?' And React will call your `render` function again, this time referencing the new state. 380 | 381 | Note that you *cannot* call `this.setState` inside a `render` function! That would be putting the cart before the horse. It's `this.setState` that 382 | 1. assigns the new values to `state` and 383 | 2. reruns `render` to display the changes. 384 | 385 | **Exercise 5**: Create a component whose background color changes when the mouse moves over it, and changes back when the mouse leaves. 386 | **Extra Credit**: Create a component that experiences three different changes in appearance when you click on it. 387 | 388 | ## Form Fields and State: Controlled and Uncontrolled 389 | 390 | Form fields (such as text input boxes) have an interesting property: if you set their `value` attribute inside a `render` function, that value **completely** controls the value of the text box—even when the user types inside of it! This is called a 'controlled' input element. This is actually very desirable in many applications—such as, for instance, only allowing certain characters to be typed in an input field. (If you don't directly set the `value` attribute, you get an 'uncontrolled' component, which is also useful.) 391 | 392 | The end result is that you need to use `this.setState` to keep the value of the text box updated while the user types, like this: 393 | 394 | ```JavaScript 395 | var InputBox = React.createClass({ 396 | getInitialState: function() { 397 | return { 398 | text: 'Type in here!' 399 | }; 400 | }, 401 | updateText: function(evt) { 402 | this.setState({ 403 | text: evt.currentTarget.value 404 | }); 405 | }, 406 | render: function() { 407 | return <input type='text' value={this.state.text} onChange={this.updateText} />; 408 | } 409 | }); 410 | 411 | React.render( 412 | <InputBox />, 413 | document.body 414 | ); 415 | ``` 416 | 417 | **Exercise 6**: Create an uncontrolled input box. 418 | 419 | **Exercise 7**: Modify the controlled input box example I gave you to (1) have no initial text and (2) prevent the user from typing the letter 'e'. (Hint: use the JavaScript `String.replace` function.) 420 | 421 | **Exercise 8**: Create a React component that renders a text box and a button. (Use a controlled text box.) When you click the button, the the current contents of the text box should be logged to the console, and the text box should be cleared. 422 | 423 | ## Passing Values from One Component to Another: Props 424 | 425 | Simple Example 426 | ```JavaScript 427 | var HelloMessage = React.createClass({ 428 | render: function() { 429 | return <div>Hello {this.props.name}</div>; //Using the props passed value ("John") 430 | } 431 | }); 432 | 433 | React.render( 434 | <HelloMessage name="John" />, //The passed value to the HelloMessage class. 435 | document.getElementById('container') 436 | ); 437 | ``` 438 | More Complex Example. 439 | Since the state of one component might end up being useful in another component, React also allows you to pass data from one component to a child component using `props`. Let's use the `<Paragraphs/>` from earlier as an example. 440 | 441 | ```JavaScript 442 | var Paragraphs = React.createClass({ 443 | render: function() { 444 | var paragraphs = this.props.text.map(function(paragraph, index) { 445 | return <p key={index}> 446 | {paragraph} 447 | </p>; 448 | }); 449 | return <div> 450 | {paragraphs} 451 | </div>; 452 | } 453 | }); 454 | 455 | var paragraphs = ['one', 'two', 'three']; 456 | React.render( 457 | <Paragraphs text={paragraphs} />, 458 | document.body 459 | ); 460 | ``` 461 | 462 | Here, we added a attribute to the `<Paragraphs>` JSX tag to pass the paragraph data to the component. Within the `render` method, we can access the data as `this.props.text` (where the label in `this.props.LABEL` corresponds to the attribute name in the JSX tag). You can have as many `props` as needed in a component, and [you can validate that a component has the `props` you expect](https://facebook.github.io/react/docs/reusable-components.html). 463 | 464 | Note what this allows you to do: you can now create components that consume state from other components. For instance, here's an example that will add a new paragraph on each click. 465 | 466 | ```JavaScript 467 | var Paragraphs = React.createClass({ 468 | render: function() { 469 | var paragraphs = this.props.text.map(function(paragraph, index) { 470 | return <p key={index}> 471 | {paragraph} 472 | </p>; 473 | }); 474 | return <div> 475 | {paragraphs} 476 | </div>; 477 | } 478 | }); 479 | 480 | var App = React.createClass({ 481 | getInitialState: function() { 482 | return { 483 | paragraphs: ['one', 'two', 'three'] 484 | }; 485 | }, 486 | clickHandler: function() { 487 | var paragraphs = this.state.paragraphs; 488 | console.log(paragraphs); 489 | paragraphs.push(paragraphs.length + 1); // changes the paragraphs array in-place 490 | this.setState({ 491 | paragraphs: paragraphs 492 | }); 493 | }, 494 | render: function() { 495 | return <div onClick={this.clickHandler}> 496 | <Paragraphs text={this.state.paragraphs} /> 497 | </div>; 498 | } 499 | }); 500 | 501 | React.render( 502 | <App />, 503 | document.body 504 | ); 505 | ``` 506 | 507 | It is not uncommon to have a single top-level component contain all the state for an app, and pass pieces of it as necessary to child components that may have state of their own. 508 | 509 | **Exercise 9**: Create a simple to-do list app with multiple components, state, and props. To show the to-do list, modify the component you created in exercise 4 to accept an array of items as `props`. Modify the component you created in Exercise 8 to 1) display the to-do list component from the previous sentence, 2) pass an array of to-dos to the to-do list component, and 3) update the array of to-dos after the user clicks add. 510 | 511 | 512 | 513 | ## Further Topics (not discussed here) 514 | 515 | - How to update a parent component's state from a child component. 516 | - [Component lifecycle](https://facebook.github.io/react/docs/component-specs.html). 517 | 518 | ---- 519 | 520 | # Answers 521 | 522 | **Answer 1**. Up to you—if it displayed as you expected on the screen, you pass! 523 | 524 | **Answer 2**. Something like: 525 | 526 | ```JavaScript 527 | var item_one = <li>One</li>; 528 | var item_two = <li>Two</li>; 529 | var item_three = <li>Three</li>; 530 | var list = <ul> 531 | {item_one} 532 | {item_two} 533 | {item_three} 534 | </ul>; 535 | 536 | React.render( 537 | list, 538 | document.body 539 | ); 540 | ``` 541 | **Answer 3**. Something like: 542 | 543 | ```JavaScript 544 | var items = ['One', 'Two', 'Three'].map(function(item, key) { 545 | return <li key={key}>{item}</li>; 546 | }); 547 | var list = <ul> 548 | {items} 549 | </ul>; 550 | 551 | React.render( 552 | list, 553 | document.body 554 | ); 555 | ``` 556 | 557 | **Answer 4**. Something like: 558 | 559 | ```JavaScript 560 | var List = React.createClass({ 561 | render: function() { 562 | var items = ['One', 'Two', 'Three'].map(function(item, key) { 563 | return <li key={key}>{item}</li>; 564 | }); 565 | return <ul> 566 | {items} 567 | </ul>; 568 | } 569 | }); 570 | 571 | React.render( 572 | <List />, 573 | document.body 574 | ); 575 | ``` 576 | 577 | **Answer 5**. Something like: 578 | 579 | ```JavaScript 580 | var blue = '#0000FF'; 581 | var red = '#FF0000'; 582 | 583 | var Stateful = React.createClass({ 584 | getInitialState: function() { 585 | return { 586 | backcolor: blue 587 | }; 588 | }, 589 | inHandler: function() { 590 | this.setState({ 591 | backcolor: red 592 | }); 593 | }, 594 | outHandler: function() { 595 | this.setState({ 596 | backcolor: blue 597 | }); 598 | }, 599 | render: function() { 600 | var divStyle = { 601 | backgroundColor: this.state.backcolor, 602 | color: '#FFFFFF' 603 | }; 604 | return <div style={divStyle} onMouseOver={this.inHandler} onMouseOut={this.outHandler}> 605 | Hello, world! 606 | </div>; 607 | } 608 | }); 609 | 610 | React.render( 611 | <Stateful />, 612 | document.body 613 | ); 614 | ``` 615 | 616 | **Answer 6**: Something like: 617 | 618 | ```JavaScript 619 | var InputBox = React.createClass({ 620 | render: function() { 621 | return <input type='text' />; 622 | } 623 | }); 624 | 625 | React.render( 626 | <InputBox />, 627 | document.body 628 | ); 629 | ``` 630 | 631 | **Answer 7**: Something like: 632 | 633 | ```JavaScript 634 | var InputBox = React.createClass({ 635 | getInitialState: function() { 636 | return { 637 | text: '' 638 | }; 639 | }, 640 | updateText: function(evt) { 641 | this.setState({ 642 | text: evt.currentTarget.value.replace('e', '') 643 | }); 644 | }, 645 | render: function() { 646 | return <input type='text' value={this.state.text} onChange={this.updateText} />; 647 | } 648 | }); 649 | 650 | React.render( 651 | <InputBox />, 652 | document.body 653 | ); 654 | ``` 655 | 656 | **Answer 8**: Something like: 657 | 658 | ```JavaScript 659 | var AddToDo = React.createClass({ 660 | getInitialState: function() { 661 | return { 662 | text: '' 663 | }; 664 | }, 665 | updateText: function(evt) { 666 | this.setState({ 667 | text: evt.currentTarget.value 668 | }); 669 | }, 670 | clickHandler: function() { 671 | console.log(this.state.text); 672 | this.setState({ 673 | text: '' 674 | }); 675 | }, 676 | render: function() { 677 | return <div> 678 | <input type='text' value={this.state.text} onChange={this.updateText} /> 679 | <button onClick={this.clickHandler}>Add</button> 680 | </div>; 681 | } 682 | }); 683 | 684 | React.render( 685 | <AddToDo />, 686 | document.body 687 | ); 688 | ``` 689 | 690 | **Answer 9**: Something like: 691 | 692 | ```JavaScript 693 | var List = React.createClass({ 694 | render: function() { 695 | var items = this.props.items.map(function(item, key) { 696 | return <li key={key}>{item}</li>; 697 | }); 698 | return <ul> 699 | {items} 700 | </ul>; 701 | } 702 | }); 703 | 704 | var AddToDo = React.createClass({ 705 | getInitialState: function() { 706 | return { 707 | text: '', 708 | items: [] 709 | }; 710 | }, 711 | updateText: function(evt) { 712 | this.setState({ 713 | text: evt.currentTarget.value 714 | }); 715 | }, 716 | clickHandler: function() { 717 | var new_item = this.state.text; 718 | var items = this.state.items; 719 | items.push(new_item); 720 | this.setState({ 721 | text: '', 722 | items: items 723 | }); 724 | }, 725 | render: function() { 726 | return <div> 727 | <List items={this.state.items} /> 728 | <input type='text' value={this.state.text} onChange={this.updateText} /> 729 | <button onClick={this.clickHandler}>Add</button> 730 | </div>; 731 | } 732 | }); 733 | 734 | React.render( 735 | <AddToDo />, 736 | document.body 737 | ); 738 | ``` 739 | -------------------------------------------------------------------------------- /React.js/WhenDoesReactCallRender.markdown: -------------------------------------------------------------------------------- 1 | # When Does React Call Render? 2 | 3 | ## Summary of guidelines 4 | 5 | 1. Keep your `render` function as fast as possible. You can do lots of computation here, but it isn't the place for computationally-heavy processes like indexing of something. 6 | 2. Extend `PureComponent` instead of `Component` if you can. This will do a [shallow comparison](../JavaScript/EqualityOfObjectsAndArraysInJavaScript.markdown) of props and state, and **only** call `render` if they are different. This may require you to design `props` or `state` in a way that complies. 7 | 3. Use `shouldComponentUpdate(nextProps, nextState)` to do the comparison of `props` and `state` yourself (for instance, if they are more complicated than the shallow comparison of `PureComponent` would allow) to avoid re-rendering. Be careful, though, that your check doesn't take more time than just `render`ing would. 8 | 9 | ## When Does React Call Render? 10 | 11 | In general, every time you call `setState` within a component (changing a component's state) or a parent component (changing a component's props). Of course, React may "batch" calls to `setState`, so that multiple `setState` calls could result in a single `render`, but `render` will get called regardless. 12 | 13 | **Additionally**, a component's render will get called **if a parent's `render` method is called**. This can yield `render` getting called much more than you expect. 14 | 15 | If you have a `PureComponent` or you've implemented `shouldComponentUpdate`, then the `setState`→`render` rules are more complicated. 16 | 17 | ## `shouldComponentUpdate(nextProps, nextState)` 18 | 19 | `shouldComponentUpdate` is a lifecycle method that gets called immediately before `render`. If it returns `false`, React will avoid calling the `render` method and assume that the result of `render` is the same as it was last time `render` was called…no change. 20 | 21 | This can be a way to get faster performance. If, for instance, you know your `render` function only depends on `this.props.x`, which is a string, you can implement something like: 22 | 23 | ```javascript 24 | shouldComponentUpdate(nextProps, nextState) { 25 | return nextProps.x !== this.props.x; 26 | } 27 | ``` 28 | 29 | to make sure we re-render **only** if the prop we care about has changed, and **not** if any other props or state have changed, and **not** just because the parent component's `render` method was called. 30 | 31 | Be aware, of course, that if you implement this function incorrectly, you can easily **not** render when you needed to, and get a UI that doesn't respond properly. 32 | 33 | ## `PureComponent` 34 | 35 | Probably the most common `shouldComponentUpdate` implementation does a shallow object comparison of props and state: if your state and props are simple and not complicated/nested data structures, this will work fine to prevent unnecessary re-renders. So, React provides an implementation of this out-of-the-box: extend `PureComponent` instead of `Component` and you'll be on your way! 36 | 37 | --------------------------------------------------------------------------------