Skip to content

Instantly share code, notes, and snippets.

@ross-u
Last active December 28, 2022 17:21
Show Gist options
  • Save ross-u/2ab3a3d1fb327c7c20c1473f1898d8e5 to your computer and use it in GitHub Desktop.
Save ross-u/2ab3a3d1fb327c7c20c1473f1898d8e5 to your computer and use it in GitHub Desktop.
React state - exercise solution

React | state ( exercise solution )


1. What is the difference between the React's function components and class components ?


Function components

Function components have props object which contains values passed to the component via props/attributes, and they don't have render or lifecycle methods.

This is the reason why they are called "functional stateless components".

Function components return a JSX string.


Class components

Class components have state and props.

Class components have render() method which renders the JSX. When creating a class component it is mandatory to create this method, otherwise the component won't work.


2. What is the component state ?

The state is an object defined inside of the React class component.

React class components have React's built-in method setState() we must use to update the state.

React's built-in setState() method triggers re-rendering of the DOM when state is changed.

Only the class component itself can define the state (object) or change it's existing state through this.setState().


Exercise


Task 1

a. Using the npm package create-react-app create new project named react-state-example. Inside off the src directory create a new directory components to store your new components.


b. Create file src/components/User.js .

Copy/paste the code provided in this gist (below) for the file User.js


c. Update the file src/App.js, by copy/pasting the code provided in this gist (below) for the file App.js.


Task 2

Add an additional property bootcamp: 'Ironhack' to the state object of the root component App.js.

Pass/set this value as the prop ( bootcampName={this.state.bootcamp} ) to each of the <User> components in App.js.

After setting the prop, update the User.js component. by adding an additional <h2></h2> tag that will show the value passed via the prop bootcampName.

This <h2> tag should show the passed value as:

<h2> Welcome To { /*Value from props bootcampName*/ }  </h2>

Task 3

Edit the clickHandler() method in root component App.js, to change state property backColor to a random color every 5 clicks.

Use the provided colorMapper function to get the random generated HEX color string.

When updating the state you must use the react setState() method.


Use the below snippet as the starting point:

src/App.js
//	src/App.js

// ...

//		...

clickHandler = () => {
  if ( /*Check click count if divisible by 5 */) {
      
      const newColor = this.colorMapper();
      const updatedCount = this.state.clickCount + 1; 
      
      // Use `this.setState()` to update the state object
  } else {
     
    const updatedCount = this.state.clickCount + 1;
    this.setState({ clickCount: updatedCount });
  }

}

Bonus

Create a new class component Navbar.js, which has a state with one property -username: 'YOUR NAME'.

Display this value in the <p> tag which will be showing in the navbar.

You can use the below snippet for your component elements.

Create a Navbar.css file and import it in the newly created component file. Use the below code snippet to add styles for the navbar.

Remember to export the newly created Navbar component.

When done, import the Navbar component in App.js component and place it as the first element so that it displays on the top of the page.

src/components/Navbar.js
// src/components/Navbar.js

// ...

//		...

//				...

     <nav id='navbar'>
       <ul>
         <a href="#"><li>Home</li></a>
         <a href="#"><li>Contact</li></a>
         <a href="#"><li>About</li></a>
       </ul>

       <div className="nav-details">
         <p className="nav-username"> Bob </p>
       </div>
     </nav>

src/components/Navbar.css
#navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background:  #352275;
  padding: 0px 40px;
}

#navbar li {
  list-style: none;
  display: inline-block;
  margin: 0px 40px; 
  font-size: 22px;
  color:white;
}

div.nav-details > * {
  display: inline-block;
  color: royalblue;
  font-size: 22px;
}


Additional resources


DOM Events in React - reactjs.org

Function vs. class components

Understanding the Fundamentals of State in React

Binding event handlers in React components

// src/App.js
import React, { Component } from 'react';
import User from './components/User';
import Navbar from './components/Navbar';
class App extends Component {
state = {
userA: {
firstName: "Harper",
avatarUrl: "https://www.refreshmiami.com/wp-content/uploads/2018/07/55085_logo-ironhack.png"
},
userB: {
firstName: "Ana",
avatarUrl: "https://s3.amazonaws.com/owler-image/logo/ironhack_owler_20180828_221413_original.png"
},
clickCount: 0,
backColor: 'yellow',
bootcamp: 'Ironhack'
};
colorMapper = () => {
const hexColor = "#" + Math.floor(Math.random() * 16777215).toString(16);
return hexColor;
};
clickHandler = () => {
if (this.state.clickCount % 5 === 0) {
this.setState({
backColor: this.colorMapper(),
clickCount : this.state.clickCount + 1
})
}
else {
this.setState( { clickCount : this.state.clickCount + 1 } );
}
};
render() {
return (
<div className="App">
<Navbar />
<h1>React - state</h1>
<p>Count is: {this.state.clickCount}</p>
<button onClick={this.clickHandler}> Click me </button>
<User
theColor={this.state.backColor}
firstName={this.state.userA.firstName}
image={this.state.userA.avatarUrl}
bootcampName={this.state.bootcamp}
/>
<User
firstName={this.state.userB.firstName}
image={this.state.userB.avatarUrl}
bootcampName={this.state.bootcamp}
/>
</div>
);
}
}
export default App;
/*
src/components/Navbar.css
*/
#navbar {
display: flex;
align-items: center;
justify-content: space-between;
background: #352275;
padding: 0px 40px;
}
#navbar li {
list-style: none;
display: inline-block;
margin: 0px 40px;
font-size: 22px;
color:white;
}
div.nav-details > * {
display: inline-block;
color: royalblue;
font-size: 22px;
}
// src/components/Navbar.js
import React, { Component } from 'react';
import './Navbar.css';
class Navbar extends Component {
state = {
username: 'YOUR NAME'
}
render() {
return (
<nav id='navbar'>
<ul>
<a href="#"><li>Home</li></a>
<a href="#"><li>Contact</li></a>
<a href="#"><li>About</li></a>
</ul>
<div className="nav-details">
<p className="nav-username">{this.state.username}</p>
</div>
</nav>
)
}
}
export default Navbar;
// src/components/User.js
import React from "react";
function User(props) {
return (
<div>
<h2 style={{ backgroundColor: props.theColor }}>
Hello, {props.firstName}
</h2>
<h2>Welcome to {props.bootcampName}</h2>
<img src={props.image} width="350" height="350"/>
</div>
);
}
export default User;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment