Codementor Events

Thinking in React

Published Jun 05, 2017Last updated Dec 01, 2017
Thinking in React

React is different in so many ways from its front-end predecessors! So much so that it triggered a renaissance in front-end and UI development in general. See Preact, Inferno, Rax to name just a few. Besides that, it also went into native UI development with React Native and now to user interfaces in VR with React VR.

React is becoming more of a standard rendering target for various platforms - web, mobile native, OS native and others. People are targeting React and adopting it in multiple platforms - a good example of this is React SketchApp, which allows React components to show up in Sketch. We've just scratched the surface of what's possible with React and the opportunities that it brings for UI development in general.

It's not about the React library

It's about the React way of thinking. We’ve gotten used to showing a user interface then mutating it to update and show the latest changes. What React did very well was to bring immutable UIs to the masses - you never "mutate" a UI - you always (re-)render it! Always run the same function that was used for the initial rendering to get the updated interface. This leads us to the main point of the React way of thinking.

It's not about React - the library. It's about the React way of thinking.

It's about declarative UIs

The main point of React is that it frees you from having to think how you transition your UI from state A to state B. This might not look like a big deal, but once you also have state C and state D and state E and so on, and have to explicitly program how you transition from A to all those states, then you begin to realise the power of React’s declarative way of describing UIs (and how difficult imperative UIs are to maintain).

Let’s look at a quick example with vanilla JS and then with React. Say we have an email input; when there is no value it should show a warning, when there is an invalid email it should show an error, and when it contains a valid email address it should hide all messages.

var emailInput = document.querySelector('.email input');
var messageDiv = document.querySelector('.email message');

emailInput.addEventListener('change', function(e){
  var value = e.target.value;
  var valid = isEmail(value);
  if (valid){
    messageDiv.removeClass('invalid');
    messageDiv.removeClass('warning');
    messageDiv.addClass('valid');
  }
  // ... handle is empty 
  // ...
})

This already looks complicated. While in React, all we do is

class extends React.Component {
  render(){
    return <div className="email">
      <input onChange={e => this.onChange(e)} />
      <div className={this.state.cls} />
    </div>
  }
  onChange(e) {
    const value = e.targe.value;
    this.setState({
      cls: isEmail(value)?
             'valid':
             value ?
               'invalid':
               'warning'
    })
  }
}

State evolving over time is the root of most UI bugs, and this is where React really shines. It frees the developer from having to think about state transitions. Conceptually your UI is being re-rendered from scratch, so there is no need to do the mutations by hand.

Conceptually, you can think of React as re-rendering the whole UI from scratch - on every change.

Small API surface

With the above example we've covered most of the React public APIs. The beauty of it all is how small of an API React introduces - it's almost too simple to be true. Yet the render method, the component props, and the component state are the most important things in a React app - getting a good grasp on these paves the way for productively using React in commercial apps.

In my 10+ years of experience, I've never found another way to write UIs so quickly and powerfully.

Of course tech is evolving naturally and getting better over time, but the jump that React has proposed is a huge leap forward. Most of the ideas are not new, they have been around for quite a while - but React has successfully managed to bring those very good ideas into a coherent library with a clear API and a small, focused purpose in mind: only build user interfaces. No data fetching, no user models, no forced app structure, etc. Although all those things have their place in UI development and are valuable, React wanted to do only one thing really well: build UIs. That's it.

React was written with only a single purpose in mind: describe & build UIs as naturally as possible.

On component props and state

Component props & component state are basic concepts in React:

  • the props of a component are passed into the component by the owner component. Component props should be treated as immutable, so they should be used as read-only by the component itself.
  • component state is stored internally in the component, and is only managed by the component itself. As a best practice, it's also good if you treat component state as immutable (although it isn't), and whenever you need to update the state, make sure you provide a new reference for each property in the state.
class ContactInfo extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      address: {
        city: 'New York',
        street: 'Chrown Str'
      }
    }
  }
  onStreetChange(city) {
    this.setState({
      address: { city, street: this.state.street }
    })
  }   
  onStreetChange(street) {
    this.setState({
      address: { street, city: this.state.city }
    })
  }
  render() {
    return <div>
      <h2>{this.props.contactName}</h2>
      <input
    	onChange={(e) => this.onCityChange(e.target.value)}
       value={this.state.address.city}
      />
      <input
    	onChange={(e) => this.onStreetChange(e.target.value)}
       value={this.state.address.street}
      />
   </div>
 }
}

const App = (props) => {
 return <div>
   {/*
     The ContactInfo components receives a props
     object like { contactName: "Richard" }
    */}
   <ContactInfo contactName="Richard">
 </div>
}

ReactDOM.render(
 <App />,
 document.querySelector('#main')
)

In the above example, notice how state is updated with a new address object on every change - this avoids skipping updates when React.PureComponent is used - which is just a React component that only re-renders when it receives new values for props and for state (it shallowly compares the old and new props objects and the old and new state objects).

In addition, React supports functional components, which cannot have state, and are called with the corresponding props object.

Understanding props and state is crucial for being productive with React.

Controlled components

Another powerful concept in React apps is controlled props - it basically means components don't store any intermediate state for the controlled props (for example on updating the value inside a text input), but rather on every change, they notify the owner component of the change, so the owner can re-render the controlled component with updated values for the props.

// controlled input
<input value={this.props.value} onChange={this.props.onChange} />

// uncontrolled input
<input defaultValue={"initial value"} onChange={this.props.onChange} />

The above inputs are example of controlled components (already baked into React), but basically this is the gist: uncontrolled components use their internal state to update their UI, while controlled components always show values from props. As a result, when owner components decide not to re-render a controlled component, even though the user may interact with the component (for example, a text input), nothing will happen and there will be no change in the UI.

Universal platform

Once you get a grasp of React and the React way of thinking about UIs, you'll suddenly realize all this knowledge can be applied to UIs everywhere, not just on the web. And the beauty of it is that in almost no time you can become productive in building native UIs for mobile or desktop operating systems, or even for the webVR now that React is becoming widely adopted, with libraries written to target multiple platforms, but with one common way of thinking about UIs - declarative and component-based.

While the old Java slogan "Write once, run everywhere" is not fit for user-interface apps written in Java, React's new approach of "Learn once, write anywhere" is really productive and life-changing.

React offers true "Learn once, write anywhere"!

I'd love to hear how you picked up React! How long did it take for you to become familiar with it? What about productivity once you grasped it?

Discover and read more posts from Radu Brehar
get started
post commentsBe the first to share your opinion
Victor H
7 years ago

The truth is that it takes too much time to be good at React but in the other hands we have Vue which is really easy to learn and it’s truly powerful, I think front-end frameworks should be developer friendly and React is not. Who is with me?

Radu Brehar
7 years ago

Well, both Vue & React are just libraries - they only solve the V (View) in MVC and not enforce a structure or other tools on you.
In my experience React is very easy to pick up - it’s just a matter of days to be productive. On the other hand, try doing that with Angular…

Arjun Raju Pillai
7 years ago

I have mixed feelings regarding Vue vs React. It’s true that the learning curve is significant… but I wouldn’t blame it on the library or JSX. For one, the documentation is awful. Secondly, the emphasis on using webpack is stressful. Yes, there’s create-react-app but it’s barely customizable. It seems like every single tutorial out there mandates that learners use webpack and additional libraries like redux.

In reality, you could do wonders with a faster and less configuration oriented tool like Brunch, and in many cases, you don’t even need a state management tool like Redux or Mobx. There’s a plethora of React tutorials out there, and I would suggest beginners to go through them rather than diving into facebook’s documentation.

Vue.js on the other hand got just about everything right. They have a more simple API, yes, but their real selling point is how easy it is to integrate the library into your app, and even when build steps may be required, they have the CLI. What’s even better is that their documentation is fantastic. Quite a few people could very easily get by with nothing but the official documentation.

That said, I’d suggest people learn React. It really makes you so much better of a Javascript developer, and it’s really fun to work with once you get the hang on it. Besides, there’s the career opportunities.

That said, I’d be careful of what I use for it in production. React’s controversial license clause is worth looking into.

Victor H
7 years ago

@ArjunRajuPillai Give this man a beer.

Rico Alexander
7 years ago

Exactly! Death to templates. Just give me the power of javascript.

Victor H
7 years ago

VueJs is better, flies away…

Radu Brehar
7 years ago

I wouldn’t just jump in another boat because of a current perf issue. The performance is good enough for most of the apps, and can be tweaked in performance critical views.

The team behind React is very solid, they work on React full time, and are showing off some amazing perf improvements with the launch of fiber reconciliation algorithm to be included in v16 of React.

Use the best tool for the job - and the one you are familiar with. For many people that’s React, while for others, it may be Vue. Competition is definitely welcomed!

Nueve Junio
7 years ago

Nah, vue.js is a copy of react :)

Victor H
7 years ago

@radubrehar You man, I like you #nohomo

Victor H
7 years ago

@nuevejunio Vue is completely different, in fact you can say Vue is a copy of Angular.

Michael Rasoahaingo
7 years ago

@radubrehar Exactly! I wouldn’t have said better!
React is not just a lib, there’s all the ecosystem and the community (not only developers but also tech team of big company like Airbnb, Zeit, etc…)

Adnan Siddiqi
7 years ago

It took years to isolate markup from JS. Thanks React for giving an excuse to write Vanilla JS again.

Show more replies