Prerequisites: some familiarity with HTML, JavaScript, and CSS. A better introduction to React? Unfortunately, most of the React tutorials out there have no consideration for best practices and don’t always teach you the “right” way to do React. In this tutorial, I will go over the basics of React, and the most common bad practices that you might encounter. This tutorial is going to be long, so make sure to get yourself some coffee! Why choose React? Before we get started, let’s stop for a moment and see why React indeed is the best choice. Declarative In React, you describe what to render (instead of telling the browser how to do it). This also means that the amount of boilerplate is greatly reduced. In React you simply start coding, it has no boilerplate that you have to generate. There’s some setup involved, but when it comes to the components, you can express them as pure functions. component Clear syntax JSX in React feels just like HTML, there’s no special syntax to learn: Learning curve Learning curve is very important when picking a UI framework. React has the least abstractions. If you know JavaScript then you can probably start writing React code in a single day. Yes, it takes time to pick up best practices, but you will be able to start very fast. Functional In my opinion, React’s greatest strength comes from the fact that you aren’t even forced to use classes. Classes over-complicate codebase without providing any benefits. In React, all of the UI can be expressed as a set of pure functions, and using pure functions to render the UI feels like a breath of fresh air. Let’s start coding! “turned on MacBook Pro beside space gray iPhone 6s, black ballpoint pen, and black Asus cordless optical mouse on top of table” by on Fabian Grohs Unsplash Now that I’ve hopefully convinced you to go with React, let’s write some code! Node.js Node.js is a JavaScript runtime environment which enables us to compile cool React code! First of all, let’s make sure that you have Node.js installed. If not, you can download it from here: https://nodejs.org/en/download create-react-app We’ll be using create-react-app from Facebook to scaffold our application. This is the most popular way to set up your environment and start coding. It comes with many required tools built-in, which helps us to eliminate many decisions. To install create-react-app globally: npm i -g create-react-app Then to scaffold your first project run: create-react-app react-intro That’s all! Now, to start the application: cd react-intronpm start This will launch a development server and will allow you to open the new and shiny React application by going to in your browser. http://localhost:3000/ Under the hood Now, let’s see how things are working under the hood. Using your IDE of choice (I recommend ) open the newly-created project. Visual Studio Code index.html Within the project go to the file. This is what you’ll see: public/index.html The part that interests us is the . This is where our React application will go. The entire root div will simply be replaced with the contents of our React application. Everything else will remain unchanged. <div id="root"></div> index.js Now let’s open . This is the file that bootstraps the entire React application. And by the way, all of our React source code will go into the directory. src/index.js src The line that does the magic is: ReactDOM.render(<App />, document.getElementById('root')); This line is a way of telling React to take our App component (we’ll discuss it in a bit), and place it within the div that was defined above within the file. root index.html Let’s now focus on the part. This looks a lot like HTML, doesn’t it? This is called JSX, and is a special JavaScript syntax that React uses to do its magic. Note that it starts with a capital — it is , not . This is a convention used by React, which allows it to disambiguate between regular HTML tags and React components that we’ve created. If you don’t start your components with a capital letter, then React won’t be able to render your components. <App /> A <App /> <app /> Whenever using JSX, we always have to import React by adding the following line within our file: .js import React from 'react'; App.js Now we’re ready to take a look at our first component. Let’s open : src/app.js In order to create a React component, we have to create a class that inherits from . That is exactly what the line does. All React components should implement a method — as you may have guessed, all of the rendering is happening within this method. The method has to return the markup to be rendered. React.Component class App extends Component render render A small side-note: the attribute is equivalent to the attribute in HTML, and is used to assign CSS classes for styling. is a reserved keyword in JavaScript, and cannot be used for an attribute name. className class class Let’s recap: The component is named App (capital A) It extends the class React.Component It has to implement the method, which returns the markup. render Bad practice #1 — Class Components everywhere There are two ways to create components in React — Class Components and Functional Components. As you may have noticed, the example above uses a Class Component. And, unfortunately, most beginner React tutorials encourage the use of Class Components. What’s wrong with Class Components? They are hard to test, tend to grow really big, prone to poor separation of concerns, couple logic with presentation (which makes debugging and testing harder). In general, you will shoot yourself in the foot by using Class Components. Especially if you’re a beginner, I would recommend staying away from them altogether. Ok, Class Components are bad, I get it. But what are the alternatives? Functional Components. If a component has nothing but the method, then it is a great candidate for refactoring into a functional component. Let’s see how the App component created by create-react-app can be improved: render See what we have done here? We’ve removed the class and replaced the method with . And if we make use of ES6 arrow functions, it is going to look even better: render function App() {...} We’ve turned the class component into a function that returns the markup to be rendered. Think about it for a moment… A function that returns the markup, there’s no unnecessary boilerplate code, just pure markup! Isn’t it beautiful? The functional component reads much better and has a higher signal-to-noise ratio. In this article, we’ll stick with Class Components, because they involve fewer abstractions, and are easier to demonstrate the core React concepts. Once you’re comfortable with React basics, I strongly recommend you to read my more in-depth article — . Mastering React Functional Components with Recompose Introducing props Props is a concept central to React. What props are exactly? Think for a second about parameters passed to a function. Props are just that — parameters passed down to a component. Here we have created a component, and we’re using it to greet John Smith from within the component. This will result in the following markup: Greetings App <div><div>Hey you! John Smith!</div></div> The curly brackets in denote JavaScript code. The component was passed and as parameters, and we simply retrieve them by accessing the object. {props.name} Greetings firstName lastName props Note that the component got passed a single object, not two values for and . props firstName lastName We can further simplify the code by making use of the ES6 object destructuring syntax: Note that was replaced with . This means that we’re only interested in those two properties of the object. And this, in turn, allows us accessing the and values directly, without having to explicitly specify . (props) ({ firstName, lastName }) props firstName lastName props.firstName What if we’ve been using instead? class components I don’t know about you, but to me, this looks much more bloated! We always have to explicitly use . this.props Single Responsibility Principle “black camera, round silver-colored analog watch, black Swiss Gear pocketknife, and black flashlight” by on Alexander Andrews Unsplash Single-Responsibility Principle is the most important programming principle to follow. It states that a module should do one thing, and it should do it well. Not following this principle alone can turn any codebase into a nightmare that is impossible to maintain. How can we violate this principle? The most common way is placing unrelated things in the same file. I’ll refer to the Single Responsibility Principle multiple times in this tutorial. Beginners usually place multiple components in the same file. Here we’ve placed the Greetings and App components within the same file. This is a bad practice because this violates the Single Responsibility Principle. Even the smallest components (like the Greetings component above) should be placed in a separate file. Let’s place the Greetings component into its own file: And then to use it within the component: App import Greetings from "./Greetings"; const App = () => (...); Make sure that the filename matches the component name. component should be placed in , component should be placed in , and so on. App App.js Greetings Greetings.js Introducing state State is another concept central to React. This is where you want to keep your data — things that may change. Storing the value typed into a form element? Use state. Keeping track of score within your game? Use state. Let’s build a simple form that takes in user’s first name. Note that I’m purposefully using a to demonstrate the concept. I demonstrate refactoring of a class component into a functional component in my other article . class component Mastering React Functional Components with Recompose Ok, the user can type his email into the form, which is great! If you’ve been paying attention, then you’ve noticed that no matter what, the name John will be used in the greeting. What if not all of our users’ names are John? We’d place ourselves in a very uncomfortable situation. How can we use the value typed into the input? In React we aren’t supposed to query the DOM directly. This is where input handlers and state come in. State is basically a plain JavaScript object that is stored as a property within the class component. Here we’re adding value to the class. SimpleForm firstName Our input now has the event handler. It fires every time when the user types a key into the input. And the property in our class handles the onChange events. firstName onChange this.onFirstNameChange Let’s take a look at the property: onFirstNameChange this.setState(...) This is how we update the state of our components. We’re not supposed to update the component state directly, only via the method. And to update the value of the state value we simply pass an object with the updated values to the method: setState firstName setState { firstName: event.target.value } In this case, is the value that was typed into the form input. In this case, this is the user’s name. event.target.value A side note: we haven’t defined as a method. This is extremely important to define it as an arrow function property on the class, and not a method. If we had defined it as a method instead, then would be bound to the form input that called the method, not to the class as we would have expected. This small detail often trips up beginners. This is another reason to avoid classes in JavaScript. onFirstNameChange this Form validation “silver iMac turned on” by on Brennan Burling Unsplash Now let’s implement simple form validation using regular expressions — let’s ensure that the first name is at least three characters long, and contains only letters. We will add another event handler for the event —it will fire whenever the user leaves the input. We will also add another property to the state — . And then we’ll display the validation error right under the input (if errors are present). onBlur firstNameError State First, we’ve added a property to the state: firstNameError state = {...firstNameError: "",}; Validation function The validation itself is happening in the arrow function above. It simply tests the input name against the regular expression: validateName validateName = name => {const regex = /[A-Za-z]{3,}/;return !regex.test(name)? "The name must contain at least three letters...": "";} If the validation fails, we return the validation error. If the validation succeeds, then we return an empty string (which signifies lack of error). We’re using JavaScript ternary expressions here to make the code terser. onBlur event handler Let’s take a look at the event handler (fires whenever the user leaves the input): onBlur onFirstNameBlur = () => {const { firstName } = this.state; const firstNameError = this.validateName( firstName ); return this.setState({ firstNameError });}; Here we extract the from the state by using ES6 object destructuring syntax. The first line is equivalent to: firstName const firstName = this.state.firstName; Then we run the validation function defined above with the , and then we set the state property with the error returned. If the validation failed, the will be set. If it succeeds, then it will be set to an empty string. firstName firstNameError firstNameError method render And now let’s take a look at the method: render() render() {const { firstNameError, firstName} = this.state;...} Here we’re once again using ES6 object destructuring to extract values from the state. <input...onBlur={this.onFirstNameBlur}/> This line assigns the function as the event handler for the event. onFirstNameBlur onBlur {firstNameError && <div>{firstNameError}</div>} Here we’re using short circuit evaluation feature of JavaScript. The div containing the will be rendered only if the value itself is truthy. firstNameError Styling “empty spiral stairs on low-angle photograph” by on Maxime Lebrun Unsplash If you’ve been following along, then you might have noticed that our form isn’t particularly pretty… Let’s change that by adding some inline styling! Styles in React are added simply by passing the styles in the attribute. style I will admit that I’m not a designer, but my programmer art is looking much better now. Here’s the form with validation error: Bad practice #3 — styling within the component Here we’ve encountered another bad practice, that unfortunately is too common — placing the styles within the method of our components. Why is this bad? This violates the Single Responsibility Principle. It also clutters our component with styles, which significantly impairs readability. render What are the remedies? Create a special object that will contain all of our styles. It is considered a good practice to place the in a separate file: style styles And then to use it within our component: SimpleForm This looks much cleaner! Takeaway: place your styles in a separate file. Adding more form fields Let’s make the form a little more interesting by adding a field to enter the last name: Not much has changed here — we’ve simply duplicated the code for the input, and also duplicated its event handlers. firstName Did I just say ? Duplicate code is a big NO in software development and should be avoided at all costs. duplicated Bad practice #4 — not splitting your components. This bad practice once again comes back to the violation of Single-Responsibility Principle. Good written code should read like a poem, and I bet that the render method of our component doesn’t read like a poem. Let’s change that. The inputs are almost identical, and both require some sort of validation. Let’s apply some refactor-fu to our component, and create a reusable component: TextField I’ve simply extracted one of the components from the method, converted it into a functional component, and passed it things that change as props: render Nice, this reads much better now! We can even go one step further, and create dedicated components for the first and last name: TextField Here we’re simply returning a pre-made component to display the first name. The is the new Object Rest syntax — this means that whatever is passed as props will be saved into the object. Then to pass the props down to the we’re using the Object Spread syntax . This takes the object, spreads its properties, and passes them down to the component. ({...rest}) rest TextField {...rest} rest TextField In other words: we take whatever was passed into , and pass it unchanged to . FirstNameField TextField And similarly, the : LastNameField This is what our form is looking like now: Much better! Why are class components so bad anyways? Class components are hard to test (unlike functional components). Poor separation of concerns: If we’re being lazy, then we’ll keep putting everything into one single class, which may grow into a 1000-line monstrosity over time (I’ve seen this happen, multiple times). Class components tend to put logic and presentation together in one single class. Which is once again bad for separation of concerns. Class components are not pure, and are hard to reason about. Functional components, on the other hand, are pure — they will always result in the same markup being rendered for the same input props. Functional components enforce good design. You’re forced to think about design. No need for the keyword, which has always been a major source of confusion. this Source code The accompanying source code can be found at GitHub What’s next? This tutorial has gotten a little longer than I was expecting. There’s still a lot to cover, especially relating to code organization, and a few other best practices. Let me know if you’re interested in hearing more in the comments. If you truly want to master React, I would strongly recommend you to check out my other article: . Mastering React Functional Components with Recompose Make sure to follow me for more articles on React and JavaScript!