Overview
In this lab, you will create a React application that demonstrates a comprehensive understanding of React principles including:
- component architecture
The mechanisms for Data passing between components Your application will consist of a central feature or theme of your choosing. Prerequisites:
Basic understanding of HTML, CSS, and JavaScript. Node.js and npm (Node Package Manager) installed on your system. Familiarity with the command line interface. Objective:
Create an interactive React web application that includes:
Five distinct components that serve different purposes in the app. CSS styling to make the application visually appealing. Data passing between components using props and state management. Fields for data entry and display, including at least one form with validation. User interaction through onClick event handlers that trigger state changes. Component navigation using either conditional rendering or React Router. Setup
Initialize a new React application using Create React App: In the command line terminal:
npx create-react-app react-interactive-web-lab
cd react-interactive-web-lab
npm start
Plan your application's feature/theme and determine the components required. Component Architecture
1. Layout Component
Create a Layout component that serves as the main container for your application.
It should include the following:
A header that displays the application title. A navigation bar or menu to move between components (if applicable). We will be using the dom routers to navigate between components: Define a Layout component with a header and navigation bar.
This example assumes you're using functional components and React Router for navigation. If you haven't installed React Router yet, you can do so by running npm install react-router-dom.
// First, you need to import necessary hooks and components from 'react-router-dom'
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
// Import your custom components
import HomeComponent from './HomeComponent';
import InputFormComponent from './InputFormComponent';
import DisplayComponent from './DisplayComponent';
import AboutComponent from './AboutComponent';
// This is your Layout component
function Layout() {
return (
<Router>
<div className="layout">
<header>
<h1>My React App</h1>
</header>
<nav>
<ul>
{/* These links should route to your different components */}
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/input">Input Form</Link>
</li>
<li>
<Link to="/display">Display</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</nav>
{/* A <Switch> looks through its children <Route>s and
renders the first one that matches the current URL. */}
<Switch>
<Route path="/about">
<AboutComponent />
</Route>
<Route path="/display">
<DisplayComponent />
</Route>
<Route path="/input">
<InputFormComponent />
</Route>
<Route path="/">
<HomeComponent />
</Route>
</Switch>
</div>
</Router>
);
}
export default Layout;
For this code to work properly, you must have the four components
(HomeComponent, InputFormComponent, DisplayComponent, and AboutComponent) defined and exported in their respective files.
Here's a simple CSS to get you started with the layout styling:
cssCopy code
.layout {
text-align: center;
}
header {
background-color: #333;
color: white;
padding: 10px 0;
}
nav ul {
list-style-type: none;
padding: 0;
}
nav ul li {
display: inline;
margin-right: 10px;
}
nav ul li a {
text-decoration: none;
color: #333;
}
/* Apply this class to the active link */
.active {
color: #555;
font-weight: bold;
}
In your CSS, make sure to design your active link appropriately, perhaps with a different color or font weight to indicate which page the user is currently viewing.
Remember, this is a functional, basic layout component. You would likely want to enhance the CSS with your own design system or use a framework like Tailwind CSS or Bootstrap to make it more aesthetically pleasing.
The CSS provided should be placed in a separate file, commonly named App.css or styles.css, which then needs to be imported into your main App.js file or the specific component file where you want to apply the styles.
Here's how you can organize the CSS:
Create a new file in your project's src directory and name it App.css. Copy the CSS provided into the App.css file. Import the App.css file into your App.js file to apply the styles to your application. Here's what the import statement in App.js would look like:
jsxCopy code
import './App.css';
Your App.js file's beginning would now look like this:
jsxCopy code
import React, { useState } from 'react';
import './App.css'; // This imports the CSS you just saved
import Home from './Home'; // Assume Home.js exists
// ... rest of your imports
This ensures that the CSS styles are loaded and applied when your React application renders. Remember that the actual names of the files can vary based on your project's setup and your personal naming conventions. The important part is to maintain consistency and to import the CSS file into your JavaScript file so that the styles are applied.
2. Home Component
Develop a Home component that serves as the landing page of your application, containing:
A brief introduction to what the app does. A visually appealing design using CSS. Below is an example of how you could structure the HomeComponent in React, including some inline CSS for styling.
You would typically keep the CSS in a separate file and import it, but for simplicity, I'll include it within the component.
Note that for a real-world application, you'd likely use a CSS framework or write more complex styles.
import React from 'react';
function HomeComponent() {
// Inline styles
const styles = {
container: {
padding: '50px',
textAlign: 'center',
},
header: {
fontSize: '2em',
color: '#333',
},
paragraph: {
fontSize: '1em',
color: '#666',
},
highlight: {
color: '#0056b3',
}
};
return (
<div style={styles.container}>
<h1 style={styles.header}>Welcome to the Space Exploration App</h1>
<p style={styles.paragraph}>
Explore the Galaxy in this Space Exploration Simulation.
</p>
<p style={{...styles.paragraph, ...styles.highlight}}>
Navigate through the simulation drills of Star Fleet Academy's Entrance Qualification Test for new Space Cadets
</p>
</div>
);
}
export default HomeComponent;
In a real application, instead of inline styles, you would probably use a separate CSS file like this:
cssCopy code
/* HomeComponent.css */
.home-container {
padding: 50px;
text-align: center;
}
.home-header {
font-size: 2em;
color: #333;
}
.home-paragraph {
font-size: 1em;
color: #666;
}
.home-highlight {
color: #0056b3;
}
Then, you would import this CSS file in your component:
jsxCopy code
import React from 'react';
import './HomeComponent.css';
function HomeComponent() {
return (
<div className="home-container">
<h1 className="home-header">Welcome to My React App</h1>
<p className="home-paragraph">
This is a simple React application that demonstrates the core concepts of React.js, such as components, state, and props.
Navigate through the app to learn more about its features. Enjoy exploring!
</p>
<p className="home-paragraph home-highlight">
Start by navigating to the Input Form to enter some data!
</p>
</div>
);
}
export default HomeComponent;
To make the home component visually appealing, consider using modern CSS techniques like Flexbox or Grid for layout, and transitions or animations for dynamic effects. You could also include images, icons, or even a carousel for a more interactive experience.
3. Input Form Component
Implement an InputForm component that allows users to submit data, with:
Input fields for collecting data. Form validation to ensure data integrity. A submit button with an onClick event handler to process and pass data to other components. InputForm component that includes basic validation and a submit handler. The input data is stored in the component's state, and when the form is submitted, it could be passed upwards via a callback function provided by a parent component, or managed by a state management library like Redux or Context API.
jsxCopy code
import React, { useState } from 'react';
function InputForm({ onSubmit }) {
const [inputData, setInputData] = useState({
name: '',
age: ''
});
const [errors, setErrors] = useState({});
// Validates the form and returns a boolean indicating if the data is valid
const validateForm = () => {
let valid = true;
let errors = {};
if (!inputData.name) {
errors.name = 'Name is required';
valid = false;
}
if (!inputData.age || isNaN(inputData.age)) {
errors.age = 'Please enter a valid age';
valid = false;
}
setErrors(errors);
return valid;
};
// Handles form submission
const handleSubmit = (event) => {
event.preventDefault();
if (validateForm()) {
onSubmit(inputData); // This would be a function passed down from the parent component
setInputData({ name: '', age: '' }); // Reset form data
setErrors({}); // Reset errors
}
};
// Updates the inputData state as the user types in the inputs
const handleChange = (event) => {
const { name, value } = event.target;
setInputData({
...inputData,
[name]: value
});
};
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="name">Name:</label>
<input
type="text"
id="name"
name="name"
value={inputData.name}
onChange={handleChange}
/>
{errors.name && <div style={{ color: 'red' }}>{errors.name}</div>}
</div>
<div>
<label htmlFor="age">Age:</label>
<input
type="number"
id="age"
name="age"
value={inputData.age}
onChange={handleChange}
/>
{errors.age && <div style={{ color: 'red' }}>{errors.age}</div>}
</div>
<button type="submit">Submit</button>
</form>
);
}
export default InputForm;
Please note the following about the code:
The onSubmit prop is expected to be a function that the parent component passes to InputForm for handling the submitted data. validateForm checks for the presence of name and that age is a number, setting errors in the state which are displayed under each input field if they exist. handleSubmit prevents the default form submission, calls validateForm, and if validation passes, it calls the onSubmit function and resets the form. handleChange updates the state with input values as they change, which allows the input fields to be controlled components. You would include this component in your app, pass it an onSubmit function from a parent component where you want to handle the form submission, and style it according to your application's design requirements.
4. Display Component
Craft a Display component that shows processed data from the InputForm, which:
Receives data through props. Updates dynamically when new data is submitted. Here's an example of a Display component that receives data through props and updates dynamically when new data is submitted from the InputForm component:
jsxCopy code
import React from 'react';
function Display({ data }) {
if (!data) {
return <div>No data to display.</div>;
}
return (
<div>
<h3>Processed Data:</h3>
<p><strong>Name:</strong> {data.name}</p>
<p><strong>Age:</strong> {data.age}</p>
</div>
);
}
export default Display;
This Display component expects a prop called data, which it uses to display the information. If data is null or undefined, it displays a message indicating there's no data to display.
To connect the InputForm and Display components, you would have a parent component that manages the state of the data and passes it to both InputForm (as a callback for onSubmit) and Display (as a prop). Here's an example of how the parent component might look:
jsxCopy code
import React, { useState } from 'react';
import InputForm from './InputForm'; // Assume InputForm is in the same directory
import Display from './Display'; // Assume Display is in the same directory
function ParentComponent() {
const [data, setData] = useState(null);
const handleFormSubmit = (formData) => {
setData(formData);
};
return (
<div>
<InputForm onSubmit={handleFormSubmit} />
<Display data={data} />
</div>
);
}
export default ParentComponent;
In the ParentComponent, when the form is submitted, handleFormSubmit is called with the form data, which updates the data state. The Display component receives the new data as props and re-renders to show the updated information.
5. About Component
Produce an About component that provides information about the app, including:
A brief description of how to use it. Here's an example of an About component that provides information about the app, including its purpose and a brief description of how to use it:
import React from 'react';
function About() {
return (
<div style={{ padding: '20px', maxWidth: '600px', margin: 'auto' }}>
<h2>About This App</h2>
<p>This app is designed to demonstrate a simple React application using functional components and state management.</p>
<h3>What does this app do?</h3>
<p>The purpose of this app is to provide a basic understanding of how React components interact with each other, how state is managed and lifted up between components, and how events are handled.</p>
<h3>How to use it?</h3>
<ul>
<li><strong>Input Form:</strong> Use the input form to submit data. The form includes validation to ensure data integrity.</li>
<li><strong>Display:</strong> View the submitted data in a formatted way. It updates automatically as new data is entered.</li>
<li><strong>Navigation:</strong> Use the navigation menu to switch between different components to learn about different functionalities.</li>
</ul>
<p>We hope this simple app helps you understand the core concepts of React development.</p>
</div>
);
}
export default About;
This component can be rendered within your application to give users information about what the application does and how they can interact with it. The styling and structure can, of course, be enhanced to fit the overall design of your app.
Updated app.js
import React, { useState } from 'react';
import Home from './Home'; // Assume Home.js exists
import About from './About'; // Assume About.js exists
import InputForm from './InputForm'; // Assume InputForm.js exists
import Display from './Display'; // Assume Display.js exists
function App() {
// This state holds the data to be displayed, initially empty.
const [displayData, setDisplayData] = useState('');
// This method is passed to InputForm and it updates the displayData state.
const handleDataSubmit = (data) => {
setDisplayData(data);
};
// This state manages which component is currently active.
const [activeComponent, setActiveComponent] = useState('home');
// This function updates the active component based on user interaction.
const navigateTo = (componentName) => {
setActiveComponent(componentName);
};
// This object acts as a simple router for the app.
const componentMapper = {
home: <Home />,
about: <About />,
inputForm: <InputForm onDataSubmit={handleDataSubmit} />,
display: <Display data={displayData} />,
};
return (
<div className="App">
<header>
<h1>My React App</h1>
<nav>
<button onClick={() => navigateTo('home')}>Home</button>
<button onClick={() => navigateTo('about')}>About</button>
<button onClick={() => navigateTo('inputForm')}>Input Form</button>
<button onClick={() => navigateTo('display')}>Display</button>
</nav>
</header>
<main>
{/* Render the active component */}
{componentMapper[activeComponent]}
</main>
</div>
);
}
export default App;
State Management
Employ React's useState hook to manage the state within your application:
Define state variables in parent components where needed. Pass state variables down to child components through props. Use the setState function to update the state when user interactions occur. User Interaction
Incorporate onClick event handlers:
Attach onClick event handlers to buttons and other interactive elements. Use event handlers to update the state and trigger UI updates. Styling
Utilize CSS to create an attractive and responsive user interface:
Write a separate CSS file for each component or use CSS-in-JS libraries like styled-components. Ensure your application is responsive and provides a good user experience on both desktop and mobile devices. Component Navigation
Implement component navigation using either:
Conditional rendering within the Layout component to switch between different views based on state. React Router to set up a multi-page application where users can navigate using URL paths. Submission
Upon completion, your project directory should include the following:
A src folder with all your components and CSS files. A public folder with your index.html and any additional assets. A README.md file with instructions on how to run your app and a brief description of its features. Commit your code to a Git repository and push it to a platform like GitHub. Provide the URL to your repository as part of your submission.
Grading Criteria
Your application will be graded based on functionality, code quality, user experience, design and creativity, and documentation. Ensure you test all functionalities and handle any errors gracefully.
Good luck, and enjoy the process of creating with React!