└── README.md
/README.md:
--------------------------------------------------------------------------------
1 | # React in 1000 words
2 |
3 | The goal of this guide is to be able to familiarize with ReactJS.
4 |
5 | You'd probably have a better time here by being already familiar with
6 | JS and ES6, but I wrote this to be easily digested by anyone
7 | who has a bit of programming background.
8 |
9 | ## Intro
10 |
11 | **React is a library for building user interfaces**: think of
12 | it as an easy way to build a view with clicks and interactions.
13 |
14 | The core of React starts with components, which are plain classes:
15 |
16 | ``` jsx
17 | class LoginForm extends React.Component {
18 | render() {
19 | return (
20 |
25 | )
26 | }
27 | }
28 | ```
29 |
30 | When React runs, it will look for a `render` method in your component and
31 | lay the HTML out based on what tags are returned by the method: in this case,
32 | we're going to be creating a form with 2 text inputs and a submit button.
33 |
34 | ## Interactions
35 |
36 | In order to add some interaction to our component, we need to introduce
37 | a concept called **state**: React components have some state that's used
38 | to keep track of what's happening in the UI.
39 |
40 | Let's add some silly validation on our login form, by making
41 | sure the user enters a password longer than 5 characters. To do so, React
42 | asks us to initialize our component with some initial state:
43 |
44 | ``` jsx
45 | class LoginForm extends React.Component {
46 | constructor(props) {
47 | super(props)
48 |
49 | this.state = {
50 | password: ''
51 | }
52 | }
53 |
54 | ...
55 | }
56 | ```
57 |
58 | Now, don't worry about understanding what those `props` are -- we'll get back at
59 | them later on. For now the most important thing is to know that if we want to
60 | manage state in our component we should initialize a `state` property in the
61 | component's constructor and assign values there.
62 |
63 | If we want to change the state, we can use `this.setState({...})` and React will
64 | patch the existing state:
65 |
66 | ``` jsx
67 | class LoginForm extends React.Component {
68 | constructor(props) {
69 | super(props)
70 |
71 | this.state = {
72 | password: ''
73 | }
74 | }
75 |
76 | render() {
77 | return (
78 |
83 | )
84 | }
85 | }
86 | ```
87 |
88 | As you see, we're now binding the value of the password field to `this.state.password`
89 | and, whenever the user types on the input, we update the state.
90 |
91 | When the state changes, React is smart enough to call the `render` method again,
92 | thus updating the UI (try typing in [this fiddle](https://jsfiddle.net/rbvrkhxz/)).
93 | This is a very important concept in React: **when state
94 | changes, the component re-renders**.
95 |
96 | Note you can't just do `this.state.password = e.target.value`,
97 | as React forces you to use the `setState` method so that it can "see" that the
98 | state has changed: if you were to update the state directly, React would have
99 | no visibility on the change.
100 |
101 | Let's "finalize" our example by handling the submit action:
102 |
103 | ``` jsx
104 | class LoginForm extends React.Component {
105 | constructor(props) {
106 | super(props)
107 |
108 | this.state = {
109 | password: ''
110 | }
111 | }
112 |
113 | onSubmit(e) {
114 | if (this.state.password.length < 5) {
115 | e.preventDefault()
116 | alert('oooops')
117 | }
118 |
119 | // Happy path code...
120 | }
121 |
122 | render() {
123 | return (
124 |
129 | )
130 | }
131 | }
132 | ```
133 |
134 | As you see, you can define interactions with inline functions:
135 |
136 | ``` jsx
137 | onChange={e => this.setState({password: e.target.value})}
138 | ```
139 |
140 | as well as component methods:
141 |
142 | ``` jsx
143 | onSubmit={this.onSubmit }
144 | ```
145 |
146 | The differences between the 2 are subtle -- don't worry about them now.
147 |
148 | ## Components altogether
149 |
150 | To build your UI, you will want to integrate multiple components together.
151 |
152 | Let's build a simple view that presents 2 login forms, one for regular users and
153 | one for admins:
154 |
155 | ``` jsx
156 | class MyView extends React.Component {
157 | render() {
158 | return (
159 |
160 |
161 |
162 |
163 | )
164 | }
165 | }
166 | ```
167 |
168 | Ouch, that was easy! In order to include components in other components you can
169 | simply "embed" them as HTML / XML tags: we have [2 forms](https://jsfiddle.net/0cv3dgko/) now!
170 |
171 | Now, you remember how I told you earlier to forget about those "props"? Let's
172 | get back to them!
173 |
174 | Say that we want to make sure the UI clearly states the forms are for different
175 | users, we can "tag" our components with different attributes:
176 |
177 | ``` jsx
178 | class MyView extends React.Component {
179 | render() {
180 | return (
181 |
182 |
183 |
184 |
185 | )
186 | }
187 | }
188 | ```
189 |
190 | and in our `LoginForm` we can access these "tags" via the `props`, which is a
191 | shortcut for "component's properties", or "properties", or "props":
192 |
193 | ``` jsx
194 | class LoginForm extends React.Component {
195 | constructor(props) {
196 | super(props)
197 |
198 | ...
199 | }
200 |
201 | render() {
202 | return (
203 |
210 | )
211 | }
212 | }
213 | ```
214 |
215 | [Et voila!](https://jsfiddle.net/ycbe2vrs/)
216 |
217 | Let's say the **props are something we inherit from our parent component**
218 | (some sort of external initialization parameters), whereas
219 | the **state is something that belongs to the component only**.
220 |
221 | As I said earlier, changing the state triggers a re-render of our component, but
222 | React is smart enough to trigger a re-render when the props change as well:
223 |
224 | ``` jsx
225 | class MyView extends React.Component {
226 | constructor(props) {
227 | super(props)
228 |
229 | this.state = {
230 | adminName: "admin"
231 | }
232 |
233 | setTimeout(_ => {
234 | this.setState({adminName: 'cthulhu'})
235 | }, 1000)
236 | }
237 |
238 | render() {
239 | return (
240 |
241 |
242 |
243 |
244 | )
245 | }
246 | }
247 | ```
248 |
249 | As simple as [that](https://jsfiddle.net/r5p942h2/)!
250 |
251 | ## Lifecycle methods
252 |
253 | As we saw, React takes advantage of your components implementing some "common"
254 | method, like `render`. There are quite a few more methods you can implement
255 | in your components that will be used by React -- let's call them [lifecycle
256 | methods](https://engineering.musefind.com/react-lifecycle-methods-how-and-when-to-use-them-2111a1b692b1)
257 | since they run at different stages of the component's lifecycle.
258 |
259 | The only method I want to mention here is `shouldComponentUpdate(nextProps, nextState)`,
260 | which allows you to decide whether the component should trigger a re-render when
261 | it receives new props (the parent changes) or new state (via `this.setState({...})`):
262 |
263 | ``` jsx
264 | shouldComponentUpdate(nextProps, nextState) {
265 | if (this.state.adminName === nextState.adminName) {
266 | alert('avoided a re-render')
267 | return false
268 | }
269 |
270 | return true
271 | }
272 | ```
273 |
274 | You can see it in action [here](https://jsfiddle.net/2fyrw3hq/).
275 |
276 | Why did I decide to mention it? Using `shouldComponentUpdate` effectively
277 | translates in good performance optimizations, since you can avoid re-rendering
278 | your components. More on this in the links at the bottom of this guide.
279 |
280 | You are now equipped with enough to start writing your first
281 | React app: let me just add a couple more paragraphs to clarify some things.
282 |
283 | ## Not only web
284 |
285 | I'd like to stress on the fact that, in my opinion,
286 | **React is an approach more than a library**: the idea is that you have
287 | re-usable components that a library (React) renders and manages, while you focus
288 | on how your components live & interact with each other.
289 |
290 | Our examples run on the browser, but the React team has been working on renderers
291 | for [mobile applications](https://facebook.github.io/react-native/docs/getting-started.html)
292 | and [VR browsers](https://facebook.github.io/react-vr/) among others.
293 |
294 | At the end of the day what changes is how to render what's returned by the `render` method,
295 | but everything else (the component's lifecycle & inner workings) stays the same
296 | across platforms.
297 |
298 | ## ...what now?
299 |
300 | We barely scratched the surface, but you should be good to go and build your
301 | first React app. A few pointers for the curious ones:
302 |
303 | * a [primer on virtual DOM](https://www.codecademy.com/articles/react-virtual-dom), which is a great performance optimization React popularized
304 | * what's this weird XML in the `render` function? Meet [JSX](https://jsx.github.io/)!
305 | * [React's top-level API](https://reactjs.org/docs/react-api.html)
306 | * how to embed a component **inside** another component tag? Meet [this.props.children](https://learn.co/lessons/react-this-props-children)!
307 | * re-rendering is sometimes expensive, so you should consider using [pure components](https://60devs.com/pure-component-in-react.html) and [immutable objects](https://github.com/facebook/immutable-js/wiki/Immutable-as-React-state)
308 | * remember when I said the differences between using methods and inline functions
309 | is subtle? [This article](https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578) will give you a good overview
310 |
311 |
312 | ```
313 | ~/projects/react-in-1000-words$ pandoc README.md | lynx -stdin -dump | wc -w
314 | 1274
315 | ```
316 |
317 | Ok, I cheated a bit...
318 |
--------------------------------------------------------------------------------