In the spirit of #100daysofmiva I'm working on simple REACT projects, alongside my Journeying with Python. I'll be sharing what I'm able to accomplish here including challenges. This project is called Accordian and it's popular for interviews so I guess it'll interest you too and not just me alone.
BTW, here's my GitHub repository for the project.
To create a new React app and its folder, I used the following command:
npx create-react-app my-app
since the the project I'm working on is called 25 Reactjs Projects, I changed the my-app in the command to 25-reactjs-projects so the command appear as npx create-react-app 25-reactjs-projects
.
In case you're having trouble creating a React App, there are a few common issues and solutions you can try:
Ensure Node.js and npm are installed:
Verify that Node.js and npm are installed by running:
node -v
npm -v
If they are not installed, download and install them from Node.js official website.
Clear npm cache:
Sometimes, clearing the npm cache can resolve issues:
npm cache clean --force
Update npm:
Make sure you have the latest version of npm:
npm install -g npm
Uninstall global create-react-app:
If you have create-react-app installed globally, uninstall it:
npm uninstall -g create-react-app
Create the React app using npx
:
Use npx
to create the React app, which ensures you’re using the latest version:
npx create-react-app my-app
Check for specific errors:
If you encounter specific error messages, they can provide clues. For example, if you see an error related to react-scripts, try deleting the node_modules folder and reinstalling dependencies:
rm -rf node_modules
npm install
Once you have app is installed, you may need to edit your src/app.js
. Editing the App.js file in the src
folder is a fundamental part of working with a React application. This file typically serves as the root component of your app, where you define the main structure and logic. Here are some key aspects of what editing App.js entails:
a. Importing Dependencies:
You usually start by importing React and other necessary modules or components.
JavaScript
import React from 'react';
import './App.css'; // Importing CSS for styling
b. Defining the Component:
The App component is defined as a function or a class. Most modern React apps use functional components.
JavaScript
function App() {
return (
<div className="App">
<header className="App-header">
<h1>Welcome to My React App</h1>
</header>
</div>
);
}
export default App;
c. Adding JSX:
JSX (JavaScript XML) is used to describe the UI. It looks similar to HTML but is written within JavaScript.
JavaScript
return (
<div className="App">
<header className="App-header">
<h1>Welcome to My React App</h1>
</header>
</div>
);
d. Styling:
You can import CSS files and apply styles to your components.
JavaScript
import './App.css';
e. Using State and Props:
You can manage state and pass props to child components to create dynamic and interactive UIs.
JavaScript
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
return (
<div className="App">
<header className="App-header">
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</header>
</div>
);
}
f. Rendering Child Components:
You can import and render other components within App.js.
JavaScript
import React from 'react';
import Header from './Header';
function App() {
return (
<div className="App">
<Header />
<main>
<p>This is the main content of the app.</p>
</main>
</div>
);
}
Accordian Project
I faced some challenges initially with my edits in the src/app.js
file, just so that you might know what to do if you face such challenges, let me explain what happened and what I did.
The error I encountered was due to an incorrect syntax in the import statement. Specifically, the name of the component project-accordian is not valid in JavaScript. I've been writing Python for sometime so it skipped my mind. This has to be either camelCase, PascalCase, or snake_case. So I just changed the name to Accordian and edited the right component, as you can see above, it compiled successfully.
So let's dive into the Accordian project. To see the complete project, click here
//Accordian project allows you to select either a single
//selection from a list or multiple section from same list.
import { useState } from "react";
import data from "./data.js"; //dummy data I found online
import "./styles.css";
export default function Accordian() {
const [selected, setSelected] = useState(null);
const [enableMultiSelection, setEnableMultiSelection] = useState(false);
const [multiple, setMultiple] = useState([]);
function handleSingleSelection(getCurrentId) {
setSelected(getCurrentId === selected ? null : getCurrentId);
}
function handleMultiSelection(getCurrentId) {
let cpyMutiple = [...multiple];
const findIndexOfCurrentId = cpyMutiple.indexOf(getCurrentId);
console.log(findIndexOfCurrentId);
if (findIndexOfCurrentId === -1) cpyMutiple.push(getCurrentId);
else cpyMutiple.splice(findIndexOfCurrentId, 1);
setMultiple(cpyMutiple);
}
console.log(selected, multiple);
return (
<div className="acc-wrapper">
<button onClick={() => setEnableMultiSelection(!enableMultiSelection)}>
Enable Multi Selection
</button>
<div className="accordian">
{data && data.length > 0 ? (
data.map((dataItem) => (
<div className="item">
<div
onClick={
enableMultiSelection
? () => handleMultiSelection(dataItem.id)
: () => handleSingleSelection(dataItem.id)
}
className="title"
>
<h3>{dataItem.question}</h3>
<span>+</span>
</div>
{enableMultiSelection
? multiple.indexOf(dataItem.id) !== -1 && (
<div className="acc-content ">{dataItem.answer}</div>
)
: selected === dataItem.id && (
<div className="acc-content ">{dataItem.answer}</div>
)}
{/* {selected === dataItem.id ||
multiple.indexOf(dataItem.id) !== -1 ? (
<div className="content">{dataItem.answer}</div>
) : null} */}
</div>
))
) : (
<div>No data found !</div>
)}
</div>
</div>
);
}
This React component, Accordian
, provides a dynamic interface where users can interact with a list of items, typically a set of questions and answers, through single or multiple selection modes. Here's a breakdown of how the code works:
1. Imports
import { useState } from "react";
import data from "./data.js";
import "./styles.css";
useState: A React hook that allows you to manage state in a functional component. Here, it is used to track the currently selected item(s).
data: The data imported from
data.js
contains an array of objects, each representing an accordion item (likely withid
,question
, andanswer
properties).styles.css: The styles imported for applying custom CSS to the component.
2. State Management
const [selected, setSelected] = useState(null);
const [enableMultiSelection, setEnableMultiSelection] = useState(false);
const [multiple, setMultiple] = useState([]);
selected: Holds the ID of the currently selected item when in single-selection mode.
enableMultiSelection: A boolean that toggles between single and multi-selection modes.
multiple: An array that holds the IDs of the selected items when in multi-selection mode.
3. Single Selection Handler
function handleSingleSelection(getCurrentId) {
setSelected(getCurrentId === selected ? null : getCurrentId);
}
- This function updates the
selected
state to the ID of the clicked item. If the item is already selected, it deselects it by settingselected
tonull
.
4. Multi-Selection Handler
function handleMultiSelection(getCurrentId) {
let cpyMutiple = [...multiple];
const findIndexOfCurrentId = cpyMutiple.indexOf(getCurrentId);
if (findIndexOfCurrentId === -1) cpyMutiple.push(getCurrentId);
else cpyMutiple.splice(findIndexOfCurrentId, 1);
setMultiple(cpyMutiple);
}
This function manages multiple selections by adding or removing the clicked item’s ID to/from the
multiple
array.If the item is not in the array, it is added; if it is already in the array, it is removed.
5. Rendering the Accordion
return (
<div className="acc-wrapper">
<button onClick={() => setEnableMultiSelection(!enableMultiSelection)}>
Enable Multi Selection
</button>
<div className="accordian">
{data && data.length > 0 ? (
data.map((dataItem) => (
<div className="item" key={dataItem.id}>
<div
onClick={
enableMultiSelection
? () => handleMultiSelection(dataItem.id)
: () => handleSingleSelection(dataItem.id)
}
className="title"
>
<h3>{dataItem.question}</h3>
<span>+</span>
</div>
{enableMultiSelection
? multiple.includes(dataItem.id) && (
<div className="acc-content ">{dataItem.answer}</div>
)
: selected === dataItem.id && (
<div className="acc-content ">{dataItem.answer}</div>
)}
</div>
))
) : (
<div>No data found!</div>
)}
</div>
</div>
);
Button: Toggles the
enableMultiSelection
mode between single and multi-selection.-
Accordion Items: The
data
array is mapped over to generate individual items. Depending on the mode, each item can be selected either singly or as part of multiple selections.- In single-selection mode, only one item’s content is shown.
- In multi-selection mode, multiple items’ contents can be shown simultaneously.
6. Conditional Rendering
- The
div
containing the content ({dataItem.answer}
) is conditionally rendered based on whether the item is selected or part of the multiple selections.
Summary:
Single Selection Mode: Only one item can be selected at a time, and selecting another item deselects the previous one.
Multi-Selection Mode: Multiple items can be selected at the same time, and each selection is independently toggled on or off.
This code provides a straightforward example of managing state and conditional rendering in React, while also introducing concepts like handling user interactions and dynamically rendering content based on user input.