Image by Franco Folini I’ve been using React for over a year now. I’m also conducting training to help people learn it from scratch. I noticed that on every training session I’m explaining the same set of concepts over and over. I think those concepts are essential if you want to “speak React”. If you are in a middle of learning it right know, you might be interested in reading this post. 1) It’s not a framework Angular or Ember are frameworks where some decisions are already made for you. React is just a library and you need to make all decisions by yourself. It focuses on helping you to build user interfaces using components. It doesn’t help you with server communication, translations, routing and so on. Some perceive this as a weakness. I agree with one wise man that once said: “Framework solves the problem of its creators” ~one of my mentors React is thin and it’s extremely easy to mix it with other 3rd party libraries. Rich JS ecosystem has a library for everything. You can choose your favorite one and plug it in without dealing with the design decisions/limitations of the framework. Of course, there is . If you feel the same way and don’t want to make every decision yourself, do a 30 min research, pick one of the , change whatever you want and just use it. famous JS fatigue opinionated starter kits/boilerplates 2) JSX When looking at React examples you’ve probably seen in action already. But React code can be written in plain JS too: JSX const rootElement =React.createElement(‘div’, {},React.createElement(‘h1’, {style: {color: ‘red’}},‘The world is yours’),React.createElement(‘p’, {},‘Say hello to my little friend’)) ReactDOM.render(rootElement, document.getElementById(‘app’)) Some people don’t fancy writing entire markup code as function calls. That’s probably why people at Facebook came up with JSX — a “syntactic sugar for the React.createElement(component, props, …children) function”. That’s why we can refactor the above example to this: const RootElement = (<div><h1 style={{color: red}}>The world is yours</h1><p>Say hello to my little friend</p></div>) ReactDOM.render(RootElement, document.getElementById('app')) During the build process will transpile the markup to plain JS. Babel 3) It’s JavaScript To generate markup dynamically in React you also use JS: <select value={this.state.value} onChange={this.handleChange}>{somearray.map(element => <option value={element.value}>{element.text}</option>)}</select> In the above example, the array is mapped using function to a list of elements. The only deviation from normal HTML here is a on element that sets the attribute for you. somearray map <option> value <select> selected It’s not required to use it though: <select onChange={this.handleChange}>{somearray.map(element => (<optionvalue={element.value}selected={this.state.value === element.value}>{element.text}</option>))}</select> Many popular frameworks use templating languages for operations like the one above. Every framework comes with its own. So every time you want to use a framework you need to learn a new templating language, its quirks and drawbacks. key The code above renders with a warning about missing property. To know why and how to solve that visit this page or just read the error message in your dev tools ;). I remember my first time using a control in Angular 1. There is a special directive that will generate all possible for you. <select> ngOptions <options> <selectng-model="selectedItem"ng-options="item as item.name for item in items"></select> To this day I don’t know what means. item as item.name for item There are smarter people than me, who memorized how to use all kinds of templating languages. I often switch from backend to frontend development. There are long periods when I’m not doing frontend at all. And the knowledge fades if you don’t use it. That’s why memorization doesn’t work for me. I’m familiar with function and HTML though, so the React way is very appealing to me. map() Another bonus is that static code analysis is free. It’s definitely easier to JS than custom templating markup. lint For me templating is String Driven Development. There is no serious linting. Just some magic in HTML which is not checked in any way. JSX adds more stuff to JS to make it more powerful. That’s also the reason I don’t agree when people call JSX a templating language. 4) It’s declarative In React you use declarative style to write your components. Let’s look at the previous example with : <select> <select value={this.state.value} onChange={this.handleChange}>{somearray.map(element => <option value={element.value}>{element.text}</option>)}</select> In this example you are not using loop to manually create a mapped collection. You are not saying just . <select> for what should be done how it should look like 5) You separate the concerns In React you keep HTML, JS and often CSS together as a component. If you want to display a row on the grid you create a component and put HTML, logic and behavior in one file. Row For many years we split JS, HTML, and CSS into different files. . It shouldn’t be confused with separation of concerns. Pete Hunt called that a separation of technologies I often get questions if I consider this “lack of separation” strange. But what’s strange for me are the examples people often give to defend the strategy of keeping HTML and JS separate: “If you keep HTML and JS in separate files you can easily replace the HTML and keep the JS intact”. It doesn’t work that way if you think about it. Most changes to the HTML structure require refactoring of JS logic. “Display logic and markup are inevitably tightly coupled” ~Pete Hunt If you change the text input to checkbox you need to rewrite your logic. No going away from that. 6) Data goes down In React data goes down the tree of the components. If you want to pass data from parent to child component you need to use . From JSX point of view props are HTML attributes. props Parent component: <div><Greetings color={red} text='Hello' /></div> In the child component, props are available under . this.props Child component: const Greetings = React.createClass({render () {const {color, text} = this.propsconst divStyle = {padding: 10, backgroundColor: 'black'}const headingStyle = {color: color} return ( <div style={divStyle}> <h1 style={headingStyle}>{text}</h1> </div> ) }}) 7) State Until now, we discussed only static components with static data passed down the components tree. Often, it’s needed to create a where the state is changing over time. stateful component Let’s consider an where you can type in a text that will be displayed below. <input> const InputBox = React.createClass({getInitialState () {return {text: ''}}, changeText (event) {this.setState({text: event.target.value})}, render () {return (<div><input type='text' onChange={this.changeText}placeholder='text' value={this.state.text} /><span>{this.state.text}</span></div>)}}) At the beginning, you set the default state of the component. In this case, we want to have an empty value. To do that you use component method that has to return state object for the component. text getInitialState() To update the state an event handler is assigned to the event. To update the state React expects you use built-in method. changeText() onChange [setState()](https://facebook.github.io/react/docs/react-component.html#setstate) The state update will be scheduled and the component will re-render when it’s done. call needs to be used to inform React about pending state change so it can apply the changes. There are no loops of any kind that track if something has changed. setState() You need to remember that is asynchronous. The results are not immediate. Examples below show both bad and good way to access the state immediately after the change is applied: setState() // BAD:// ...someFunction (value) {this.setState({someValue: value})// may not be changed at this pointconsole.log('New value: ', this.state.someValue)}// ... // GOOD:// ...someFunction (value) {this.setState({someValue: value}, () => {// do stuff with new stateconsole.log('New value: ', this.state.someValue)})}// ... Ok, but what if there is a need to propagate the state changes to the parent component? 8) Events go up Let’s say we have a component that needs to get the data from the child from the previous example. Parent InputBox const Parent = React.createClass({gimmeThatState (textFromInput) {console.log(textFromInput)// or this.setState({text: textFromInput})}, render () {<InputBox pushChangesUp={this.gimmeThatState} />}}) component passes down a function (as a prop) that can be used by to push some data up. Parent InputBox The updated could look like this: InputBox const InputBox = React.createClass({propTypes: {pushChangesUp: React.PropTypes.func.isRequired}, getInitialState () {return {text: ''}}, changeText (event) {this.setState({text: event.target.value})}, pushChangesUp () {this.props.pushChangesUp(this.state.text)} render () {return (<div><input type='text' onChange={this.changeText}placeholder='text' value={this.state.text} /><span>{this.state.text}</span><button onClick={this.pushChangesUp}>Push changes up</button></div>)}}) The first thing you see is a property at the beginning of the component declaration. It’s used to validate the props. For me, it serves a similar purpose as an interface in OOP. By looking at I immediately know what I need to provide to the component to make it work. propTypes propTypes Next, the local event handler is assigned to the event on a button. When clicked, the function uses from props to push the data up. pushChangesUp() onClick pushChangesUp() Now, component can save the data in its own state and pass it down to a different component. Parent 9) How rendering works Every call informs React about state changes. Then, React calls method to update the components representation in memory ( ) and compares it with what’s rendered in the browser. If there are changes, React does the smallest possible update to the DOM. setState() render() Virtual DOM Child components know that they need to re-render because their props changed. I often compare that to a diff mechanism in Git. There are two snapshots of component tree that React compares and just swaps what needs to be swapped. I was looking for a clever diagram describing the render flow but couldn’t find one. You can read more about it though. here 10) Composition is the key Parent components that own the state are often referred to as . They are responsible for state management and rendering children (this sounds so odd). Child components are used to trigger event handlers passed down from parents (like the component in previous examples) and to display the data. container components InputBox Child components that are responsible for displaying the data are called . presentational components Container component is often responsible for fetching data, API calls (see lifecycle method) and so on. You should keep this in one place to avoid side-effects in presentational components. Those should be as dumb as possible about everything other than displaying the data. [componentDidMount()](https://facebook.github.io/react/docs/react-component.html#componentdidmount) This separation of concerns and terminology were popularized by Dan Abramov, the author of . You can read more about it in . Redux his article You can see that it all fits together. When every component follows single responsibility principle it can be composed with others and reused. The biggest challenge is to figure out how to divide those responsibilities and where to put the state. If you want to know more about the topic search for articles. “thinking in react” 11) Keep the state small On my training, there is often an exercise involving some kind of list filtering. Let’s say you have a list of todos: const initialState = [{id: 1, text: 'laundry'},{id: 2, text: 'shopping'}// ...] const List = React.createClass({getInitialState () {return {todos: initialState}}, render () {return (<div><ul>{this.state.todos.map(todo => <li key={todo.id}>{todo.text}</li>)}</ul></div>)}}) And now, you want to add a search box. 50% people would go with some variation of this approach: const initialState = [{id: 1, text: 'laundry'},{id: 2, text: 'shopping'}// ...] const List = React.createClass({getInitialState () {return {todos: initialState,filteredTodos: null}}, search (searchText) {const filteredTodos = this.state.todos.filter(todo =>todo.text.indexOf(searchText) > 0) this.setState({filteredTodos: filteredTodos}) }, render () {// get todos from stateconst {filteredTodos, todos} = this.state // if there are filtered todos use them const list = filteredTodos === null ? todos : filteredTodos return ( <div> <SearchBox onChange={this.search} /> <ul> {list.map(todo => <li key={todo.id}>{todo.text}</li>)} </ul> </div> ) }}) What you can see here is duplicated state, two sources of truth and introduction of spaghetti code. Just imagine that you want to update one of the todos with search filter turned on. What’s better? Keep the state as small as possible. If something can be then it should be. calculated on the fly Here is a better solution: const initialState = [{id: 1, text: 'laundry'},{id: 2, text: 'shopping'}// ...] const List = React.createClass({getInitialState () {return {todos: initialState,searchText: null}}, search (searchText) {this.setState({searchText: searchText})}, filter (todos) {if (!this.state.searchText) {return todos} return todos.filter(todo => todo.text.indexOf(this.state.searchText) > 0) }, render () {const {todos} = this.state return ( <div> <SearchBox onChange={this.search} /> <ul> {this.filter(todos).map(todo => <li key={todo.id}> {todo.text} </li>)} </ul> </div> ) }}) Here you keep only the that is used to filter the list before rendering. A much cleaner approach, a smaller state, and no duplication. searchText 12) Conditional rendering In the previous example, the list was rendered depending on some conditional logic. It’s often needed to render one part of the markup if some conditions are met, and the other if they are not. In React there are a few ways to do that. Ternary operator In JSX it’s possible to use to perform conditional rendering: ternary operator React.createClass({getInitialState () {return {hideTodos: true}}, render () {return (<div>{hideTodos ? 'Sorry there is no data' : <TodoList />}</div>)}}) Possible variations: ternary operator outside expression return if/else block outside expression return Helper function React.createClass({getInitialState () {return {hideTodos: true}}, renderTodos () {if (this.state.hideTodos) {return 'Sorry there is no data'} return <TodoList /> } render () {return (<div>{this.renderTodos()}</div>)}}) A useful approach, but when the component is bigger you need to jump up and down between the helper and a method. render() A component This is probably the cleanest approach, works well as a . feature toggle React.createClass({getInitialState () {return {hideTodos: true}}, render () {return (<div><HideIf condition={this.state.hideTodos}><TodoList /></HideIf></div>)}}) const HideIf = React.createClass({render () {if (this.props.condition) {return <span>'Sorry there is no data'</span>} // children is what's inside <HideIf> element return this.props.children }}) 13) You don’t need Flux Probably the most common misconception among React newcomers is that you need to use it with Redux or some other Flux implementation. Redux is great. It’s the most popular Flux implementation thanks to , lots of features and clean, functional, testable approach. . great tutorials But you might not need it If you are learning React, if your app is small, if you don’t need global state or you don’t have any problems with tracking the state changes in your app — . don’t use it If you want to know more read about it . here Wrap-up So, this was my list of React concepts I discuss with people the most. I highly recommend reading as it is the best source of knowledge if you read it from cover to cover. I also recommend watching early React videos (from ~2013–2014) . It will help you recognize if you have similar problems or you should stick to some other technology. React docs describing what problems Facebook was trying to solve when they created React and React would help you Originally published at aimforsimplicity.com .