├── .gitignore ├── README.md ├── favicon.ico ├── package-lock.json ├── package.json ├── project-files ├── adopt-me.png ├── petfinder-client.js ├── reset.css └── style.css ├── public └── index.html └── src ├── App.js ├── Pet.js ├── PetList.js ├── SearchControls.js ├── actionCreators.js ├── actions.js ├── adopt-me.png ├── credentials.js ├── index.js ├── petfinder-client.js ├── reducers.js ├── reset.css ├── store.js └── style.css /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # production 7 | build 8 | 9 | # misc 10 | .DS_Store 11 | npm-debug.log 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React + Redux 2 | 3 | Welcome to the React + Redux workshop. The stated purpose of this workshop to get you up to speed on building apps using React and Redux, two of very useful tools to have in your toolbox. We'll be using a few other tools during this workshop but these will be largely be glossed over since they're not the focus of the workshop. Plus, thanks to [create-react-app][cra] these tools are mostly hidden from you anyway. 4 | 5 | ## Prerequisites 6 | 7 | - Have [node.js][node] 4+ installed 8 | - Have a solid foundation in JavaScript 9 | - ES6 experience is nice but not required 10 | 11 | ## Why Listen to Me 12 | 13 | My name is Brian Holt and I used to work at Netflix as a UI engineer mostly writing React and Node. Previously I worked at reddit where I launched [reddit's first React code][reddit-react]. I've been writing React for nearly 4 years which is pretty much eternity when it comes to React: it's only been public since March 2013. Luckily for you, I've run into a lot of pitfalls with React and I'm happy to share my experience with you about methods of development that I found useful. 14 | 15 | ## Let's Write React. Right Now. 16 | 17 | Open a new file (anyway, doesn't matter; maybe on your desktop) and call it `whatever-you-want.html`. Put the following markup in there: 18 | 19 | ```html 20 | 21 | 22 | 23 | 24 | Document 25 | 26 | 27 |
nothing rendered yet
28 | 29 | 30 | 33 | 34 | 35 | ``` 36 | 37 | We are now ready to write some Reacts. We're including both React and ReactDOM from unpkg (thanks Michael Jackson, author of React Router.) These two packages are required to React up and going. React is the package common amongst React (for web,) React Native, A-Frame React (for WebVR,) React-Blessed (for CLI,) etc. It's the basic architecture of React; it has no concept of how to render itself, only how to create new components. ReactDOM is what takes the components we're about to create and actually renders them out to the DOM. It's the connecting layer between the code and the actual view. 38 | 39 | Okay, open this page in a browser. `File >> Open` and then select the file and open it should work. You should see `nothing rendered yet`. Put the following code into the open script tag: 40 | 41 | ```javascript 42 | var markupExample = React.createElement('h1', {}, 'lolol') 43 | ReactDOM.render(markupExample, document.getElementById('root')) 44 | ``` 45 | 46 | The hello world of React. Here we've created an h1 with the text of 'lolol' and rendered it out to the DOM. Cool. The empty object are the attributes being passed to the div. If you give a property of `{id: 'my-h1'}` the rendered component will be `

lolol

`. 47 | 48 | The ReactDOM stuff is taking your top level element (we'll be making more very shortly) and puts inside of some DOM element which we grab with `getElementById`. Let's do some nesting! 49 | 50 | ```javascript 51 | // replace everything in the script tag so far 52 | var markupExample = React.createElement('div', {}, 53 | React.createElement('h1', {}, 'My Favorite Cites to Visit'), 54 | React.createElement('ul', {}, 55 | React.createElement('li', {}, 'Tel Aviv'), 56 | React.createElement('li', {}, 'Reykjavik'), 57 | React.createElement('li', {}, 'Amsterdam'), 58 | React.createElement('li', {}, 'Rome'), 59 | React.createElement('li', {}, 'Hong Kong') 60 | ) 61 | ) 62 | 63 | ReactDOM.render(markupExample, document.getElementById('root')) 64 | ``` 65 | 66 | Here we are making some nested markup. This is the way to do with React. You can write as many children as you need; just separate with commas. Or use an array. Either works. Let's make this a tiny bit more readable. 67 | 68 | ```javascript 69 | // replace the codes again 70 | const ce = React.createElement 71 | var markupExample = ( 72 | ce('div', {}, 73 | ce('h1', {}, 'My Cities to Visit'), 74 | ce('ul', {}, 75 | ce('li', {}, 'Tel Aviv'), 76 | ce('li', {}, 'Reykjavik'), 77 | ce('li', {}, 'Amsterdam'), 78 | ce('li', {}, 'Rome'), 79 | ce('li', {}, 'Hong Kong') 80 | ) 81 | ) 82 | ) 83 | 84 | ReactDOM.render(markupExample, document.getElementById('root')) 85 | ``` 86 | 87 | This makes it so you don't have to write `React.createElement` a bunch of times. 88 | 89 | We also use `()` to put `div` on its own line. This makes the indentation line up as you would expect it to. It's for readability. 90 | 91 | Let's try adding some styling. 92 | 93 | ```javascript 94 | // replace
  • 95 | ce('li', {style: {color: 'red'}}, 'Tel Aviv'), 96 | ce('li', {style: {color: 'mediumspringgreen'}}, 'Reykjavik'), 97 | ce('li', {style: {color: 'rebeccapurple'}}, 'Amsterdam'), 98 | ce('li', {style: {color: 'peru'}}, 'Rome'), 99 | ce('li', {style: {color: 'darkslate'}}, 'Hong Kong') 100 | ``` 101 | 102 | To change styles in React, we're operating on the style object which is how you do it in JavaScript anyway. But this is how you add properties to a component in React. Okay, since is a bit verbose; let's try to not repeat ourselves so much. 103 | 104 | ```javascript 105 | // replace everything in script tag 106 | var FavoriteCity = () => { 107 | return ( 108 | ce('li', {style: {color: 'red'}}, 'House of Cards') 109 | ) 110 | } 111 | 112 | var App = () => ( 113 | div({}, 114 | h1({}, 'My Favorite Cities to Visit'), 115 | ul({}, 116 | ce(FavoriteCity, {}), 117 | ce(FavoriteCity, {}), 118 | ce(FavoriteCity, {}), 119 | ce(FavoriteCity, {}), 120 | ce(FavoriteCity, {}) 121 | ) 122 | ) 123 | ) 124 | 125 | ReactDOM.render(markupExample, document.getElementById('root')) 126 | ``` 127 | 128 | So now we have a component called FavoriteCity that is being used in another component. FavoriteCity is called a _composite component_, or a component we've made comprised of other components. But this is less useful than it was before: we only have one show now with one color. Let's fix that. 129 | 130 | ```javascript 131 | // replace render in FavoriteCity 132 | var FavoriteCity = () => { 133 | return ( 134 | li({style: {color: this.props.titleColor}}, this.props.titleName) 135 | ) 136 | } 137 | 138 | // replace
  • s 139 | ce(FavoriteCity, {titleColor: 'peru', titleName: 'Tel Aviv'}), 140 | ce(FavoriteCity, {titleColor: 'rebeccapurple', titleName: 'Reykjavik'}), 141 | ce(FavoriteCity, {titleColor: 'lawngreen', titleName: 'Rome'}), 142 | ce(FavoriteCity, {titleColor: 'mediumspringgreen', titleName: 'Amsterdam'}), 143 | ce(FavoriteCity, {titleColor: 'thistle', titleName: 'Hong Kong'}) 144 | ``` 145 | 146 | Okay, this is looking more useful. We have a flexible component that we can give properties from parent (`App`) to the child (`FavoriteCity`). Note that `FavoriteCity` cannot modify that state; it can only read from that. Only the parent can decide which props to give the child; the child just had to deal with it. This is an important concept in React that we'll continue to explore. Let's do one more thing before we add JSX. What if we want to make it so we can click the links and they would toggle if they were bolded or not? 147 | 148 | ```javascript 149 | class FavoriteCity extends React.Component { 150 | constructor { 151 | this.state = { 152 | fontWeightState: 'bold' 153 | } 154 | } 155 | render () { 156 | return ( 157 | li( 158 | { 159 | style: { 160 | fontWeight: this.state.fontWeightState, 161 | color: this.props.titleColor 162 | } 163 | }, 164 | this.props.titleName 165 | ) 166 | ) 167 | } 168 | } 169 | ``` 170 | 171 | Try playing with the initial value of fontWeightState. You'll see that each component has its own state. We are then free to play with that state. Also notice I'm calling the state variable `fontWeightState`: this is a terrible name since it's redundant. However I wanted to show you there's no magic names here: name these variables whatever you want. Let's make it so it toggles boldness back and forth. 172 | 173 | ```javascript 174 | class FavoriteCity extends React.Component { 175 | constructor { 176 | this.state = { 177 | fontWeightState: 'bold' 178 | } 179 | } 180 | toggleFontWeight () { 181 | var fontWeightState = (this.state.fontWeightState === 'bold') ? 'normal' : 'bold' 182 | this.setState({fontWeightState}) 183 | } 184 | render () { 185 | return ( 186 | li( 187 | { 188 | onClick: this.toggleFontWeight, 189 | style: { 190 | fontWeight: this.state.fontWeightState, 191 | color: this.props.titleColor 192 | } 193 | }, 194 | this.props.titleName 195 | ) 196 | ) 197 | } 198 | } 199 | ``` 200 | 201 | This is how you make the components respond to interaction. And notice that state is mutable via the `setState` API. State is mutable (can be changed) while props are immutable (cannot be changed.) We give it an onClick property which points to a method we want to call once that particular event happens. There's also onSubmit, onChange, etc. Notice all we have to do is setState and then React will handle the rest: it'll kick off a re-render and update the DOM for you. We just have to tell React "Given these states and props, our component will look like this." That's what rad about React: we just have to tell it what to look like for a given set on inputs. You don't have to reason any more about it than that. Also, it's cool that each component is managing its own state: some can be bolded and some not. 202 | 203 | Okay, this syntax is manageable for React, but there's a better way. This gets unruly in big apps. Let's move to JSX 204 | 205 | ## JSX 206 | 207 | JSX is a tiny extension to JavaScript specifically for React (though other frameworks like [deku][deku] use it too.) It let's you add "XML-like syntax" to your JavaScript. In other words, you can write HTML directly in your JavaScript. This sounds gross and nasty and one definitely one of the reasons people get turned off React. This is why I showed you how to write React without a build step first. Now you've seen what it's like to write React without JSX: let me show how adding the JSX HTML syntax can make your code easier to read and maintain. 208 | 209 | Add the following script tag above your other script tags. 210 | 211 | ```html 212 | 213 | ``` 214 | 215 | Change the opening script tag of your code block from `