Working with jsx and components in React – A beginners guide

I finally got around to working with React a UI framework that I was always curious about. This blog post describes me playing around with it. It’s meant to be unofficial so don’t quote me on any of this stuff.

Installation

Installation is pretty simple. Follow the GitHub link here to go to a starter repo.

npx create-react-app helloreact
cd helloreact
npm start

Once you have installed react following the commands above your app would be started. Mines ran on http://localhost:3000/. So you could check there to see the completed application.

Simple Component

Now we are going to create our first component. We create a file hello.js and in it we place the following code.

import React from 'react';

const HelloWorld = () => (
  <p>Hello World</p>
);

export default HelloWorld;

That’s what a simple component looks like. We import react and then we create a function that renders hello world. We export the function that is assigned to the constant HelloWorld.

In the App.js file we now import our HelloWorld component by adding one line as shown below.

import HelloWorld from './hello';

We can then use the HelloWorld component in our render function. Take note of the <HelloWorld/> tag. This is our component in html format.

    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <HelloWorld/>
      </header>
    </div>

Once we do this we get the following output seen in the picture. Well without the we are happy part. But you can add that if you wish. Just edit the hello.js file.

Props in React

Props is data we can pass to our components using what would be usually known as html attributes. The data is available in our component via the props object. Lets look at it below.

Lets look at props next. We can pass in data to our components using props. Lets modify our helloworld component to accept some arguments.

import React from 'react';

const HelloWorld = (props) => (
  <p>{props.message}</p>
);

export default HelloWorld;

In the paragraph tag we use curly braces to output a message from the props data. In our main component we send in a message. The format is like adding an attribute to an html tag.

<HelloWorld message="hello world we are happy"/>

Whatever is in message will output to the web page.

Class Components

Now we are going to fetch data from an api. In order to do this we convert our main app from a function to a class component.

We make these changes to modify our app shown below.

First we get component from the react module.

import React, {Component} from 'react';

Then we change the function to a class like

class App extends Component {

}

We add a render function to show our html output. Before we did this directly from the function.

  render (){
        return (
            <div className="App">
                <header className="App-header">
                    <img src={logo} className="App-logo" alt="logo" />
                    <HelloWorld message="hello world we are happy"/>
                </header>
            </div>
        )
  };

Thats it our app should work the same.

Pulling data from an api

Lets try pulling some data from an Api. In App.js we create some functions to pull from a sample Api. The main one is shown below. Called getUsers. We use it to pull data from the Api.

   getUsers = () => {
        fetch('https://reqres.in/api/users?page=2')
            .then(rsp=>rsp.json())
            .then(data =>{
                this.setState({users:data});
                console.log(this.state.users);
            })
    }

Some important things to note. The this.setSate is special. Its allows us to hold information in memory and pass to our views. The reqres is a great test api service. Next we use a function that is part of the react component lifecycle. It is called componentDidMount.

 componentDidMount(){
       this.getUsers();
    }

We call the getUsers function within the componentDidMount function. In our render function we pass the data from the getUsers that is stored in the state.

 render (){
        return (
            <div className="App">
                <header className="App-header">
                    <img src={logo} className="App-logo" alt="logo" />
                    <HelloWorld user={this.state.users}/>
                </header>
            </div>
        )
  };

We can get data from our state variable by calling this.state. At the top of our component we initialize the state object as shown below.

  state = {};

In our HelloWorld component we display the data in a maybe unconventional way. We first check the props to see if we have what we need

if(props.user){
    // jsx here
 }

Then we render our outputs hard coding style. This is really just to test.

  if(props.user){
        return( 
            <p>{props.user.data[0].first_name}</p>,
            <p>{props.user.data[1].first_name}</p>,
            <p>{props.user.data[2].first_name}</p>
            )
    }else{
        return <p>Working</p>;
    }

Some things to note. In jsx this is how I know to display different elements. I return open and close brackets inside of list of html elements separated by commas. Its different kind of thing but not really confusing.

   return (
       <html>Tag</html>
       )

Now lets change the HelloWorld component to display the name of the users in one tag. First we modify hello.js file to only take props.

   if(props){
        return (
            <p>First name: {props.first_name}<br/>
                Last name:  {props.last_name}
            </p>
        )

We need the first_name and last_name in our props variable. Then in our App.js we use the map function to send in the correct props to our helloworld component. This will also display multiple HelloWorld components.

         return (
              <div className="App">
                  <header className="App-header">
                      <img src={logo} className="App-logo" alt="logo" />
                      {this.state.users.data.map((user) => <HelloWorld first_name={user.first_name} last_name={user.last_name}/>)}
                  </header>
              </div>
          )

Things to note

In the App.js we have to also consider that the data is not initially available to render and provide an alternative

// check if the state has the users data
    if(this.state.users){
    
    }

If the data is not available we render something else.

   return (
              <div className="App">
                  <header className="App-header">
                      <img src={logo} className="App-logo" alt="logo" />
                      <p>loading</p>
                  </header>
              </div>
          )

Working with buttons

Now lets add a button and work on getting click events. The first thing we do is add the button. So we have something like

  <div className="App">
                  <header className="App-header">
                      <img src={logo} className="App-logo" alt="logo" />
                      <button>Load More</button>
                      {this.state.users.data.map((user) => <HelloWorld first_name={user.first_name} last_name={user.last_name}/>)}
                  </header>
              </div>

You can see the load more button above. Now we create a function in our App.js file. We use this function to get the click event. The function is called onLoadButtonClick.

  onLoadButtonClick = (e) => {
        this.id += 1;
        if(this.id == 3){
            this.id = 1;
        }
        this.getUsers(this.id);
        console.log("button clicked");
    }

This function loads the getUsers function to retrieve more users. We made modifications to the getUsers function so we can send the page number we want to receive.

  getUsers = (id) => {
        fetch('https://reqres.in/api/users?page='+ id)
            .then(rsp=>rsp.json())
            .then(data =>{
                this.setState({users:data});
                console.log(this.state.users);
            })
    }

So we pass in an id and append it to the Api URL and we can change the page number. In our click function we repeat the page numbers because we only have two pages 1 and 2.

if(this.id == 3){
            this.id = 1;
        }

So we reset the page counter back to one if the number is greater than two. Clicking the load more button changes the result set.

Adding filtering to your app

Lets add search functionality. In order to do searching we make a few changes. On the search input we add a new function called onSearchChange. This function is responsible for reacting when the input text changes. It will search the list for a match. Lets look at it below.

    onSearchChange = (e) => {
       const searchQuery = e.target.value;
       this.filterUsers(searchQuery);
       console.log(searchQuery);
    }

We get the query using e.target.value. We then call the filterUsers function and pass the query as an argument. What does filterUsers do lets look at it below.

  filterUsers = (name) => {
        const filteredUsers = this.users.filter((u)=>u.first_name == name);
        if(name && filteredUsers.length > 0){
            this.setState({users:filteredUsers})
        }else{
            this.setState({users:this.users})
        }
    }

In the code above we use the filter JavaScript function to search for the first_name in the list. If we find a match we set the state with the new list otherwise we show the original list. In order to do this we have to create a default list. In the getUsers function we do below

this.users = response.data;
this.setState({users:response.data});

So this.users is where we store the default list when we get the data from the Api. Then we set it to the state object as users. So once the text changes these things happen and we can see the list for what we search for.

Conclusion

Alrite that’s a little introduction to react. A very interesting JavaScript framework that is used all over the web.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s