React Beginner: Part IV

Murli Prajapati
Bit Shift
Published in
6 min readMay 13, 2018

Finishing app’s components

In last article, we created three main components of the app and then added them to App component. In this article, we will create remaining three simple components and will do some lifting.

The three components i.e. TodayComponent, ListComponent and GraphComponentthat we are going to create are quite simple. Their job is just to display the data which is being passed as props. For now, we will hard code the data and will replace them when we will get forecast data from API. So, let’s start Reacting.

Creating TodayComponent:

This component will show forecast for current day. Create the component’s three files and add this code to TodayComponent.jsx.

Here you can find that we are using utility method that we created at the end of last article. One more thing to note here is that the windSpeedUnit variable. Celsius and meter/second are part of the Metric unit system and Fahrenheit along with miles/hour come under the Imperial unit system. So toggling between Celssius and Fahrenheit will also change the wind speed unit.

As like the markup, css is also quite long of this component but the result is beautiful and responsive. You get it from here.

Creating ListComponent:

This component will display forecast of next six days. Create a ListComponent folder in src/component/ and then create those three essential files. Add the following markup in ListComponent.jsx

Here we are iterating over data array and generating markup for single list item containing day, temperature, weather icon and weather description. Array.map() will return a new array having six SingleListItem components. The hard-coded data will be dealt with when we have actual data. We are also showing the icon based on weather id as we did in TodayComponent.

The prop key is of importance here as it helps react to uniquely identify elements which have changed added or removed from the list. A unique value of key improves list rendering performance of React. You can read more about the importance of key here.

Here is the css for ListComponent.css.

Creating GraphComponent:

Ahh..You know the drill. Be ready with the component in src/components.

To plot a simple line chart showing the temperature variation over a week we will use react-sparklines.

Install react-sparklines by running this command.

npm install react-sparklines --save

Add this code in GraphComponent.jsx

Here is the GraphComponent.css.

With this, we are done with all of our apps components. Now we will add these newly created components to the App.jsx.

You also need to update the App.css. Get it from here.

With this final css in place, you should have a responsive but non-functional weather app which looks something like this.

Run the app using npm run start command and go to http://localhost:8080.

Lift up..!!

Before we dive into the network request stuff, we need to learn a very important concept/pattern of React which is “Lifting state up”. React docs have explained it very well here. So let’s see how it fits our app.

Right now our app tree structure looks like this:

Components which plays key role for data fetching are SearchBox and UnitComponent as on new input or unit change we are going to fetch new data.

Those components hold two values in their local state i.e. queryString and unit.

Keep in mind that weather API requires mainly two parameters i.e. city name/zipcode and temperature unit i.e. Metric or Imperial.

Let’s consider two cases here:

Case 1:

Assume that default unit is Celsius and the search input is empty. So when we type a city name in input and hit the search button to get data, we realize that we don’t have any information about currently selected unit because that info is in UnitComponent’s local state.

Case 2:

Assume that we have fetched the data in SearchBox component by hard-coding the Celsius unit in API URL. Now when we try to change the unit by clicking on C or F, how do you think the SearchBox component will get to know about the change in the unit so that it can fetch new data for a new unit and current city? Good question right?

So here we know that both of our components are out of sync and need to communicate to each other. That’s where lifting of state comes into the picture.

The trick here is to take component’s local state and give it to common ancestor so that state’s values can be made available using props to children.

In our case, the common ancestor of SearchBox and UnitComponent is Navbar component. So we will remove the queryString and unit from their respective components and add them to Navbar. But wait…let’s think once more about the state. Once we move the state up to Navbar and fetch the forecast, the data is still in Navbar. How will our other components get the forecast…oops, we are stuck again…

No worries…we just learnt how we can lift the state up. The common ancestor of Navbar and rest of the components is App component. So put everything in App component.

So the final idea is to take queryString and unit from SearchBox and UnitComponent, add to App component then fetch data and pass it using props to other components.

Let’s start heavy lifting…with easy one

— Open UnitComponent.jsx

— Remove this.state from constructor…you know what…remove the whole constructor.

— Remove this.setState from changeUnit() method.

— Add this.props.onUnitChange(newUnit) in changeUnit method. onUnitChange() is a prop that has reference of a function in Navbar. Yes, we can do that. So whenever we change unit, we will send the unit to Navbar by calling this.props.onUnitChange(newUnit) function.

— Replace this.state.unit with this.props.unit in render method. We will pass unit as a prop from Navbar component.

Now your UnitComponent will look like this.

We need to do some changes in Navbar.jsx. Remember the function reference that we passed as props, let’s create that.

Notice how we passed the reference of sendNewUnitToParent to UnitComponent using props. So sendNewUnitToParent will be called on every unit change event.

At this point, Navbar is aware of unit changes. We will apply this same trick to make App component aware of it. sendNewUnitToParent will call changeUnit function which is being passed by App to Navbar. Let’s look at that one also.

Here we have added unit and queryString to App’s local state and are passing current unit as prop. Navbar’s changeUnit prop passes the reference of onUnitChange function. So eventually this function will be executed on every unit change.

Just to tell you…this.setState() function is asynchronous so your changes in state won’t be reflected immediately. That’s why it expects a callback function as its second argument which will be called when the state gets updated. We passed the notifyStateChange function as a callback function.

At this point, if you change the unit in UnitComponent it will get reflected in App’s state.

State lifting in SearchBox component

I am sure you are convinced that state lifting is very tedious task even for a single state variable and this component has two events handling a single state variable i.e. handleQueryChange and handleSearch.

We will use a simple trick here so that we only need to handle a single event i.e., handleSearch.

What we will do is we will keep a variable in component’s local state to track the changes and when the user clicks search button we will change the queryString variable value in App’s local state. Cool…Right.

After these changes your component will look like this:

Here this.props.searchSubmit is a function provided by Navbar.

Do the following changes in Navbar.jsx.

And finally, modify App.jsx.

Now if you enter something in search box or change the unit, App component will know about these in notifyStateChange method and it can keep every other components in sync. That’s what we wanted to achieve.

If you have made this far then you can understand what is prop drilling (read “So why use context?” section) and can admire the beauty of state management libraries such as Redux or MobX. Recently, React added the Context API in stable version which eliminates prop drilling and state lifting.

We have laid the foundation for data fetching as we have both unit and city/zipcode to get forecast data.

Let’s meet at the next episode of this series. React Beginner: Part V.

If you liked this article don’t forget to clap 👏. If you have any suggestion or query feel free to post here in comments or ping me on twitter.

--

--

Murli Prajapati
Bit Shift

Full Stack Developer | Android Developer | Hobbyist Gamer