Understanding React Component

Image for post
Image for post

Components are the heart and soul of React. Most simply component is just a function that accept some properties and return a UI element.

Components take raw data and render it as HTML in the DOM. It describes what to render. They utilize properties (props for short) and states which contribute to this raw data. Both props and states are plain Javascript objects.

There are three ways to create a component.

A) React traditionally provided the React.createClass method to create component classes (its deprecated now).

B) Using the ES6 syntax with extends React.Component, which extends the Component class instead of calling React.createClass.

C) And the third way, is creating the React Stateless Functional Components.

Create a React component using ES6 syntax

The constructor() method is automatically called when an object is created, and gives us chance to do any initialization work required to make the object useful. This only gets called once for each object, and you never call it directly. As with other OOP languages, constructor() is invoked when an instance of this class is created. Furthermore, if we create a constructor() method, you almost always need to invoke super() inside of it, otherwise the parent’s constructor won’t be executed.

The super() method is a special method that means “call this same method on whichever class I inherited from.”

So, class ChatComponent extends React.Component means our ChatComponent gets all the functionalities provided by its parent class, React.Component. It also means that it’s good practise to let React.Component do its own initialization if it needs to, which is what super() does: it tells the parent class to go ahead and run the same method on itself before we can continue. And constructor() takes the component’s props as its only input parameter. This must get passed on with the super() so that the parent class can act on those props as needed.

Component returns exactly one DOM element. Just like in HTML everything has to have one parent DOM element, in other words one top-level element. So, if I have a component that looks something like below:

I will need to modify by either bringing in a single wrapper element like below:

OR nesting the one of the top-level <div> inside the other like so:

And the third way to create component is for React Stateless Functional Components

This is a new syntax/pattern for defining components as a function of props. It was introduced in React v0.14. From the release notes

“In idiomatic React code, most of the components you write will be stateless, simply composing other components. We’re introducing a new, simpler syntax for these components where you can take props as an argument and return the element you want to render”. Lets look at some some examples of Stateless Functional Component

This pattern is similar to the “traditional” one, except for the fact that we’re using simple functions instead of methods defined in a class. This can be useful when we want to extract functions out of the class (e.g for readability and cleanliness sake).

A functional component is just a function. It’s not a class. As such, there’s no global this object. This means that when we’re doing a render we’re basically creating a new instance of a ReactComponent, thus leaving out the possibility for these javascript objects to communicate with each other via some global this. This also makes the use of state and any life-cycle methods impossible as a consequence.

Generally, using the new pattern is recommended whenever possible! If we only need a render method, but no life-cycle methods or state, use this functional component pattern.

Properties

Props (short for properties) are a Component’s configuration. They are received from above and immutable as far as the Component receiving them is concerned. That is, once a component receives its props, render may use it to display data in the HTML, but the props object will not change. A Component cannot change its props, but it is responsible for putting together the props of its child Components. Props do not have to just be data — callback functions may be passed in as props. When a component is rendered, it can access its “props” using this.props. In the code above, the Chat component uses this.props.chat

Per React’s Thinking in React documentation, props are best explained as “a way of passing data from parent to child.” That’s it. In essence, props are just a communication channel between components, always moving from top (parent) to bottom (child). A quick example:

So what’s happening here? First, notice that we have two separate components and . In this example, we want to pass data from Parent component to child (FoodsList) component using props. The data we want to pass from our parent to our child is a short list of food names (the array assigned to the foods property on our parent component).

To pass them to the child, we define a property on that child component where that data will be passed through. In this case, we define a property or “prop” in React-terminology called tacos on the component. Next, using the JSX curly braces syntax for specifying JavaScript code within our markup, we grab our array of foods from the parent by calling this.foods. Here, we’re literally saying to the component, “here’s a list of foods, go nuts.”

Realize: our component could’nt care less about what data it’s getting as long as 1.) that data is passed through a prop called foods and the type of data is an Array. If we look at the definition of our component, we can see how this works.

Like we’d expect, we’re pulling in our array of foods from the component by calling to this.props.foods from within our (or child) component. This resolves the first requirement. Next, we call .map() on this value to iterate over it, meaning, we expect the value to be an array.

From there, we assign a variable in our map’s arguments to reference each value being iterated over taco and then use it accordingly (in this case, we just print the name of the food on to the page).

States

The state is a data structure that starts with a default value when a Component mounts. It may be mutated across time, mostly as a result of user events. A Component manages its own state internally. Besides setting an initial state, it has no business fiddling with the state of its children. You might conceptualize state as private to that component. For example, the user clicks a button, types in an input field, or receives new data from a WebSocket server. These events would update a property in the component’s state by calling setState(), and the update is rendered in HTML.

Difference between Props and States

  • state are mutable, props are not
  • state means internal data of a class; props means ,the data which is transferred through the components.
  • If a Component needs to alter one of its attributes at some point in time, that attribute should be part of its state, otherwise it should just be a prop for that Component.

Should this Component have state?

The props vs state summary is beautifully given in this guide. I am taking a bit of summary from that page.

State is optional. Since state increases complexity and reduces predictability, a Component without state is preferable. Even though you clearly can’t do without state in an interactive app, you should avoid having too many Stateful Components.

Component types

Stateless Component — Only props, no state. There’s not much going on besides the render() function. Their logic revolves around the props they receive. This makes them very easy to follow, and to test.

This Hello World script is a good example of a stateless component:

To have a smaller syntax for stateless components, React provides us with a function style. We create a function that takes properties as an argument and returns the view. Requiring the HelloWorld component as a function that returns <h1> would be:

Stateful Component — These are used when your component must retain some state. This is a good place for client-server communication (XHR, web sockets, etc.), processing data and responding to user events. These sort of logistics should be encapsulated in a moderate number of Stateful Components, while all visualization and formatting logic should move downstream into many Stateless Components.

It is often desirable to divide components based on their primary responsibilities, into Presentational and Container components. Presentational components are concerned only with displaying data — they can be regarded as, and are often implemented as, functions that convert a model to a view. Typically they do not maintain any internal state. Container components are concerned with managing data. This may be done internally through their own state, or by acting as intermediaries with a state-management library such as Redux. Initialization of the state and update of the state are handled in container component.

Updating state

When a Component needs to have and manage its state we usually write the Component as a class, and have its state live in the class constructor function.

We can not update state by modifying the state object directly (i.e. this.state.price = 1900;). This is wrong and won’t work, as React doesn’t watch the state object for changes. Instead, React exposes us with the setState method that we can pass updated state values to.

Only place we can directly write to this.state should be the Components constructor (or, if we’re using class-properties plugin a babel-preset, the class declaration) . In all the other places you should be using this.setState function, which will accept an Object that will be eventually merged into Components current state. Although its possible to alter state by writing to this.state directly, it will not lead to the Component re-rendering with new data, and generally lead to state inconsistency.

Props and state are quite closely related. The state of one component will often become the props of a child component. Props are passed to the child within the render method of the parent as the second argument to React.createElement() or, if we are using the more familiar syntax with tag attributes, then..

<MyChild name={this.state.childsName} />

The parent’s state value of childsName becomes the child’s this.props.name. From the child’s perspective, the name prop is immutable. If it needs to be changed, the parent should just change its internal state:

this.setState({ childsName: 'New name' });

and React will propagate it to the child for you. A natural follow-on question is: what if the child needs to change its name prop? This is usually done through child events and parent callbacks. The child might expose an event called, for example, onNameChanged. The parent would then subscribe to the event by passing a callback handler.

So I will have something like below in the parent component.

<MyChild name={this.state.childsName} onNameChanged={this.handleName} />

The child would pass its requested new name as an argument to the event callback by calling, e.g., this.props.onNameChanged(‘New name’), and the parent would use the name in the event handler to update its state. So, I will have the following code in child component.

We cannot set new state values until the component has been mounted. Lets look at another example from an app that shows an interactive 30-Day Bitcoin Price Graph. Here, the DataBox component fetches real time Bitcoin price-data from the CoinDesk API every 90 seconds. The data is formatted and then displayed to the user along with changes since last month.

Note how setState() works. In the above we pass an object to setState() containing parts of the state we want to update. In other words, the object we pass would have keys (“currentPrice”, “monthChangeD” and so on) corresponding to the keys in the component state, then setState() updates or sets the state by merging the object to the state. The object form of setState() is great when setting state that isn’t concerned with previous state. When fetching Bitcoin price date, we know the new value and don’t care what the previous value was. So, we replace it wholesale.

componentDidMount() is invoked immediately after a component is mounted. And as we needed to load data from a remote endpoint, we instantiate the network request from componentDidMount()

setState() expects either an object or a function as the first parameter. However, you could pass both an object and a function, but React would treat it differently. If you pass an object as the first parameter and then pass a function as the second parameter, the function would be treated as a callback function, not updater function.

Think about what happens when setState() is called. React will first merge the object I pass to setState() into the current state. Then it will start what React calls the reconciliation process. The reconciliation process is the way React updates the DOM, by making changes to the component based on the change in state. When the request to setState() is triggered, React creates a new tree containing the reactive elements in the component (along with the updated state). This tree is used to figure out how this component’s UI should change in response to the state change by comparing it with the elements of the previous tree. React knows which changes to implement and will only update the parts of the DOM where necessary.

It will create a new React Element tree (an object representation of our UI), diff the new tree against the old tree, figure out what has changed based on the object you passed to setState() , then finally update the DOM. In other words, when setState is called, it marks the component as dirty (which means it needs to be re-rendered). The important thing to note is that although render method of the component is called, the real DOM is only updated if the output is different from the current DOM tree (a.k.a diffing between the Virtual DOM tree and document’s DOM tree).

Written by

MachineLearning | DataScience | DeepLearning. Previously Frontend Engineer. Ex International Banking Analyst. https://www.linkedin.com/in/rohan-paul-b27285129/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store