├── .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 `