I would like to know how to define number of cards per row. I want to have 4 cards maximum in a row currently all new cards are added into the row.
It's whole bootstrap.
import Card from "react-bootstrap/Card";
import { Link } from 'react-router-dom';
// import DetailComponent from "../Detail/Detail";
import "./ListingCard.css";
export default function ListingCardComponent({handleShow, property}) {
return (
<div className="container">
<div class="col">
<Card style={{ height: "30rem", width: "18rem" }} onClick={handleShow} className="box">
{/* <a href="/user/listingdetail"> */}
<Link href="/user/listingdetail" params={property._id}>
<Card.Img variant="top" src={property.image} height="255px" />
<Card.Body>
<Card.Title>{property.address}</Card.Title>
<Card.Subtitle className="mb-2 text-muted">Price:${property.rent}</Card.Subtitle>
<Card.Text>Bedroom {property.bedrooms} Bathroom {property.bathrooms}</Card.Text>
</Card.Body>
</Link>
{/* </a> */}
<button type="button" class="btn btn-default btn-lg">
<svg
xmlns="http://www.w3.org/2000/svg"
width="40"
height="40"
fill="currentColor"
class="bi bi-bookmark-heart"
viewBox="0 0 16 16"
>
<path
fill-rule="evenodd"
d="M8 4.41c1.387-1.425 4.854 1.07 0 4.277C3.146 5.48 6.613 2.986 8 4.412z"
/>
<path d="M2 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v13.5a.5.5 0 0 1-.777.416L8 13.101l-5.223 2.815A.5.5 0 0 1 2 15.5V2zm2-1a1 1 0 0 0-1 1v12.566l4.723-2.482a.5.5 0 0 1 .554 0L13 14.566V2a1 1 0 0 0-1-1H4z" />
</svg>
</button>
</Card>
{/* <DetailComponent property={property}/> */}
</div>
</div>
);
}
Related
I have a contact button in my header I want it to render a modal when clicked. I create state variables for the click event and imported a modal component into my header file. I've tried making a handleClick function for the onClick event as well as don't it without this as you will see. I can't quite see why I can't get it working. I've googled the sh*t out of this with nothing seems to help.
header file:
import React, { useEffect, useState } from "react";
import { Link as LinkScroll } from "react-scroll";
import ButtonOutline from "../misc/ButtonOutline";
import Modal from "../Modal";
const Header = () => {
const [modalOpen, setModalOpen] = useState(false);
const [activeLink, setActiveLink] = useState(null);
const [scrollActive, setScrollActive] = useState(false);
useEffect(() => {
window.addEventListener("scroll", () => {
setScrollActive(window.scrollY > 20);
});
}, []);
return (
<>
<header
className={
"fixed top-0 w-full z-30 bg-white-500 transition-all " +
(scrollActive ? " shadow-md pt-0" : " pt-4")
}
>
<nav className="max-w-screen-xl px-6 sm:px-8 lg:px-16 mx-auto grid grid-flow-col py-3 sm:py-4">
<div className="col-start-1 col-end-2 flex items-center">
<h1 className="h-8 w-auto text-2xl font-Amatic text-black-500 hover:text-green-500 cursor-pointer">
Soul Amiga
</h1>
</div>
<ul className="hidden lg:flex col-start-4 col-end-8 text-black-500 items-center">
<LinkScroll
activeClass="active"
to="home"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("home");
}}
className={
"px-4 py-2 mx-2 cursor-pointer animation-hover inline-block relative" +
(activeLink === "home"
? " text-green-500 animation-active "
: " text-black-500 hover:text-green-500 ")
}
>
Home
</LinkScroll>
<LinkScroll
activeClass="active"
to="about"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("about");
}}
className={
"px-4 py-2 mx-2 cursor-pointer animation-hover inline-block relative" +
(activeLink === "about"
? " text-green-500 animation-active "
: " text-black-500 hover:text-green-500 ")
}
>
About
</LinkScroll>
<LinkScroll
activeClass="active"
to="mywork"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("mywork");
}}
className={
"px-4 py-2 mx-2 cursor-pointer animation-hover inline-block relative" +
(activeLink === "mywork"
? " text-green-500 animation-active "
: " text-black-500 hover:text-green-500 ")
}
>
My Work
</LinkScroll>
<LinkScroll
activeClass="active"
to="blog"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("blog");
}}
className={
"px-4 py-2 mx-2 cursor-pointer animation-hover inline-block relative" +
(activeLink === "blog"
? " text-green-500 animation-active "
: " text-black-500 hover:text-green-500 ")
}
>
Blog
</LinkScroll>
</ul>
<div className="col-start-10 col-end-12 font-medium flex justify-end items-center">
<ButtonOutline
onClick={() => {
setModalOpen(true);
}}
>
Contact
</ButtonOutline>
<Modal open={modalOpen} />
</div>
</nav>
</header>
{/* Mobile Navigation */}
<nav className="fixed lg:hidden bottom-0 left-0 right-0 z-20 px-4 sm:px-8 shadow-t ">
<div className="bg-white-500 sm:px-3">
<ul className="flex w-full justify-between items-center text-black-500">
<LinkScroll
activeClass="active"
to="home"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("home");
}}
className={
"mx-1 sm:mx-2 px-3 sm:px-4 py-2 flex flex-col items-center text-xs border-t-2 transition-all " +
(activeLink === "home"
? " border-green-500 text-green-500"
: " border-transparent")
}
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
Home
</LinkScroll>
<LinkScroll
activeClass="active"
to="about"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("about");
}}
className={
"mx-1 sm:mx-2 px-3 sm:px-4 py-2 flex flex-col items-center text-xs border-t-2 transition-all " +
(activeLink === "about"
? " border-green-500 text-green-500"
: " border-transparent ")
}
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"
/>
</svg>
About
</LinkScroll>
<LinkScroll
activeClass="active"
to="mywork"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("mywork");
}}
className={
"mx-1 sm:mx-2 px-3 sm:px-4 py-2 flex flex-col items-center text-xs border-t-2 transition-all " +
(activeLink === "mywork"
? " border-green-500 text-green-500"
: " border-transparent ")
}
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
My Work
</LinkScroll>
<LinkScroll
activeClass="active"
to="blog"
spy={true}
smooth={true}
duration={1000}
onSetActive={() => {
setActiveLink("blog");
}}
className={
"mx-1 sm:mx-2 px-3 sm:px-4 py-2 flex flex-col items-center text-xs border-t-2 transition-all " +
(activeLink === "blog"
? " border-green-500 text-green-500"
: " border-transparent ")
}
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
/>
</svg>
Blog
</LinkScroll>
</ul>
</div>
</nav>
{/* End Mobile Navigation */}
</>
);
};
export default Header;
modal file:
import React from "react";
import ButtonPrimary from "./misc/ButtonPrimary";
function Modal({ open }) {
if (!open) return null;
return (
<div className="modalBackground">
<div className="modalContainer">
<button> X </button>
<div className="title">
<h1>Soul Amiga</h1>
</div>
<div className="body">
<p>Name</p>
<p>Email</p>
<textarea />
</div>
<div className="footer">
<ButtonPrimary text="Send" />
</div>
</div>
</div>
);
}
export default Modal;
I have a mySQL database with about 100 rows, containing the data of products I'm listing in an eCommerce app.
I have them displayed on the front-end by using Axios to get the rows from my back-end SELECT * statement. They are then held as an array state const [rows, setRows] = useState([]);.
These rows are then mapped for each row found in the table, so around 100 maps.
I have noticed with this many results performance has started to become an issue and I've heard similar issues from mapping arrays.
I've benchmarked and tinkered to find that this component is the one causing the performance issues.
I would like any solutions to improve my component's performance, without altering the structure too much.
Heres the component
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Button from '#mui/material/Button';
export default function ProductCard(props) {
const [rows, setRows] = useState([]);
const isntDesktop = props.isntDesktop; //Constant from parent
const isMobile = window.innerWidth < 768; //Checks if screen is smaller than mobile
const sidebar = props.sidebar; //Sidebar state from parent component
useEffect(() => {
axios.get('http://localhost:8080/products/get/')
.then(res => {
setRows(res.data);
}).catch(err => {
console.log(err);
});
});
return (
rows
.sort((a, b) => a.name.localeCompare(b.name))
//Map products
.map((row, index) => {
return (
/* Adjust structure for mobile */
isMobile ? (
/* Product card */
<div
key={index}
class={`${
sidebar ? 'border-0' : 'border'
} relative mt-6 py-8 px-5 rounded`}
>
{/* Heading */}
<h2 class="text-2xl font-semibold tracking-wide text-gray-700">{row.name}</h2>
<div class="flex items-center sm:items-start space-x-5">
{/* Image */}
<img
src={row.image}
alt="product"
class={`${
sidebar ? 'opacity-50' : 'opacity-100'
} mt-4 min-w-[125px] sm:w-[300px] h-auto`}
/>
<div class="mt-4">
{/* Price */}
<p class="text-2xl sm:text-xl font-semibold sm:font-medium text-gray-600">£ {row.price}</p>
{/* Keywords */}
<ul class="ml-5 mt-2 space-y-1">
<li class="list-disc text-gray-600">{row.keyword_one}</li>
<li class="list-disc text-gray-600" >{row.keyword_two}</li>
<li class="list-disc text-gray-600">{row.keyword_three}</li>
</ul>
</div>
</div>
<div
class={`${
sidebar ? 'bg-none' : 'bg-gray-100'
} mt-4 py-2 px-4 flex justify-center space-x-2.5`}>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 text-sky-500">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 18.75a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h6m-9 0H3.375a1.125 1.125 0 01-1.125-1.125V14.25m17.25 4.5a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h1.125c.621 0 1.129-.504 1.09-1.124a17.902 17.902 0 00-3.213-9.193 2.056 2.056 0 00-1.58-.86H14.25M16.5 18.75h-2.25m0-11.177v-.958c0-.568-.422-1.048-.987-1.106a48.554 48.554 0 00-10.026 0 1.106 1.106 0 00-.987 1.106v7.635m12-6.677v6.677m0 4.5v-4.5m0 0h-12" />
</svg>
<label class="text-gray-600 text-sm">Free delivery on orders over £50</label>
</div>
<div class="mt-4 w-full mx-auto flex flex-col sm:flex-row space-y-2.5 sm:space-y-0 sm:space-x-2.5">
{sidebar && isntDesktop ? (
<Button
type="submit"
variant="contained"
sx={{
opacity: 0.5,
bgcolor: '#6366f1',
textTransform: 'none',
width: '100%',
':hover': {
backgroundColor: '#4f46e5',
},
}}
>
View product
</Button>
) : (
<Button
type="submit"
variant="contained"
sx={{
opacity: 1,
bgcolor: '#6366f1',
textTransform: 'none',
width: '100%',
':hover': {
backgroundColor: '#4f46e5',
},
}}
>
View product
</Button>
)}
<Button
type="submit"
sx={{
border: ' 1px solid #38bdf8',
color: '#38bdf8',
textTransform: 'none',
width: '100%',
':hover': {
color: '#ffffff',
backgroundColor: '#38bdf8',
},
}}
>
Add to cart
</Button>
</div>
</div>
) : (
<div key={index} class="flex mt-6 py-8 px-5 border rounded">
{/* Image */}
<img src={row.image} alt="product" class="mr-4 w-[300px] h-auto" />
<div class="relative w-full px-5 items-center">
{/* Heading */}
<h2 class="text-2xl font-semibold tracking-wide text-gray-700">{row.name}</h2>
<div class="mt-8 flex justify-between">
{/* Keywords */}
<ul class="ml-5 space-y-1">
<li class="list-disc text-gray-600">{row.keyword_one}</li>
<li class="list-disc text-gray-600" >{row.keyword_two}</li>
<li class="list-disc text-gray-600">{row.keyword_three}</li>
</ul>
{/* Promo */}
<div class="flex flex-col ml-5">
{/* Price */}
<p class="text-xl font-medium text-gray-600">£ {row.price}</p>
<div
class={`${
sidebar ? 'bg-none' : 'bg-gray-100'
} mt-4 py-2 px-4 flex space-x-2.5`}>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 text-sky-500">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 18.75a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h6m-9 0H3.375a1.125 1.125 0 01-1.125-1.125V14.25m17.25 4.5a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h1.125c.621 0 1.129-.504 1.09-1.124a17.902 17.902 0 00-3.213-9.193 2.056 2.056 0 00-1.58-.86H14.25M16.5 18.75h-2.25m0-11.177v-.958c0-.568-.422-1.048-.987-1.106a48.554 48.554 0 00-10.026 0 1.106 1.106 0 00-.987 1.106v7.635m12-6.677v6.677m0 4.5v-4.5m0 0h-12" />
</svg>
<label class="text-gray-600 text-sm">Free delivery on orders over £50</label>
</div>
</div>
</div>
<div class="absolute bottom-0 w-full pr-5 flex space-x-2.5">
{sidebar && isntDesktop ? (
<Button
type="submit"
variant="contained"
sx={{
opacity: 0.5,
bgcolor: '#6366f1',
textTransform: 'none',
width: '100%',
':hover': {
backgroundColor: '#4f46e5',
},
}}
>
View product
</Button>
) : (
<Button
type="submit"
variant="contained"
sx={{
opacity: 1,
bgcolor: '#6366f1',
textTransform: 'none',
width: '100%',
':hover': {
backgroundColor: '#4f46e5',
},
}}
>
View product
</Button>
)}
<Button
type="submit"
sx={{
border: ' 1px solid #38bdf8',
color: '#38bdf8',
textTransform: 'none',
width: '100%',
':hover': {
color: '#ffffff',
backgroundColor: '#38bdf8',
},
}}
>
Add to cart
</Button>
</div>
</div>
</div>
)
)
})
)
}
Since you (probably) want to fetch your data once (on mount), you will have to add an empty dependency array to your useEffect to avoid infinitely running a query . You can read more about it here: https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects (In the Note section).
useEffect(() => {
axios.get('http://localhost:8080/products/get/').then(res => {
setRows(res.data);
}).catch(err => {
console.log(err);
});
}, [])
I saw that you render all your data on render and unfortunately, React is notoriously slow when it comes to rendering large lists. You might need to think about windowing your data, aka rendering a chunk of your data when your page first load and render more data as the user scroll further down. There's a great library that handles this for you: https://tanstack.com/virtual/v3/docs/guide/introduction.
I hope this helps!
I have two components, one will contain a button that will trigger the cart icon change when clicked, while the second component will contain the cart icon to be changed. I have tried but i have not been able to achieve this.Here is an image to explain better
Component A
import React,{useState} from 'react'
const Cart = () => {
const [itemCount, setItemCount] = useState('');
return (
<div>
<button
style={{width: '10%', height: '10%', padding:'20px'}}
onClick={() => {
setItemCount(itemCount + 1);
}}
>
{" "}
</button>
</div>
)
}
export default Cart
Component B
import React from 'react'
import Cart from './Cart'
const CartShow = (props) => {
return (
<div style={{border: '2px solid red', background: 'black', width: '30%', margin: '100px',
padding: '30px'}}>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M9 22C9.55228 22 10 21.5523 10 21C10 20.4477 9.55228 20 9 20C8.44772 20 8 20.4477
8 21C8 21.5523 8.44772 22 9 22Z" stroke="white" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
<path d="M20 22C20.5523 22 21 21.5523 21 21C21 20.4477 20.5523 20 20 20C19.4477 20 19
20.4477 19 21C19 21.5523 19.4477 22 20 22Z" stroke="white" stroke-width="2" stroke-
linecap="round" stroke-linejoin="round"/>
<path d="M1 1H5L7.68 14.39C7.77144 14.8504 8.02191 15.264 8.38755 15.5583C8.75318 15.8526
9.2107 16.009 9.68 16H19.4C19.8693 16.009 20.3268 15.8526 20.6925 15.5583C21.0581 15.264
21.3086 14.8504 21.4 14.39L23 6H6" stroke="white" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
{props.itemCount}</svg>
<Cart/>
</div>
)
}
export default CartShow
Assuming your code works except the state change. following should work(not tested):
Component A
const Cart = (props) =>
<div>
<button
style={{width: '10%', height: '10%', padding:'20px'}}
onClick={() => props.setItemCount(props.itemCount + 1)}
>
{" "}
</button>
</div>
export default Cart
Component B
import React,{useState} from 'react'
import Cart from './Cart'
const CartShow = () => {
const [itemCount, setItemCount] = useState(0);
return (
<div style={{border: '2px solid red', background: 'black', width: '30%', margin: '100px',
padding: '30px'}}>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M9 22C9.55228 22 10 21.5523 10 21C10 20.4477 9.55228 20 9 20C8.44772 20 8 20.4477
8 21C8 21.5523 8.44772 22 9 22Z" stroke="white" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
<path d="M20 22C20.5523 22 21 21.5523 21 21C21 20.4477 20.5523 20 20 20C19.4477 20 19
20.4477 19 21C19 21.5523 19.4477 22 20 22Z" stroke="white" stroke-width="2" stroke-
linecap="round" stroke-linejoin="round"/>
<path d="M1 1H5L7.68 14.39C7.77144 14.8504 8.02191 15.264 8.38755 15.5583C8.75318 15.8526
9.2107 16.009 9.68 16H19.4C19.8693 16.009 20.3268 15.8526 20.6925 15.5583C21.0581 15.264
21.3086 14.8504 21.4 14.39L23 6H6" stroke="white" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
{itemCount}</svg>
<Cart itemCount={itemCount} setItemCount={setItemCount} />
</div>
)
}
export default CartShow
Edit: to show the numbers on on the cart, check this link: How to put the number at top right corner of cart icon?
Since Cart is a child of CartShow you should move the state to CartShow ( or have a different parent component that contains both of them ). Then pass a func down to Cart to update itemCount
Here's the code:
<div className="flex flex-wrap -mx-2 mb-8">
{props &&
props.item.map((data, i) => (
<div
key={i}
className="w-full md:w-1/2 lg:w-1/4 px-2 mb-4 flex rounded justify-center items-center p-2 m-1"
>
<h1>abc</h1>
<svg
xmlns="http://www.w3.org/2000/svg"
width="100px"
height="140"
fill={url(`#color-${i}`)}
viewBox="0 0 30 45"
aria-hidden="true"
style={{ transform: `translate(0, -20px)` }}
>
<defs>
<linearGradient id={`color-${i}`} x1="0%" y1="100%" x2="0%" y2="0%">
<stop offset={`${min(7, threshold)}%`} stop-color="rgb(40, 134, 248)" />
<stop offset={`${data.humidity}%`} stop-color="rgb(255, 0, 0)" />
<stop stop-color="rgb(227, 227, 227)" />
</linearGradient>
</defs>
<path stroke="#2886f8" d="M15 6
Q 15 6, 25 18
A 12.8 12.8 0 1 1 5 18
Q 15 6 15 6z" />
</svg>
</div>
))}
</div>
What I'm trying to do here is to fill the linearGradient. but the problem is when I try to do this:
<svg fill={url(#color-${i})}>
it doesn't work. the error is Cannot find name 'url'. the choices to import is the import { url } from 'inspector';.
cause the svg it looks like this.
You should interpolate the string templates correctly.
fill={`url(#color-${i})`}
The url is a reference to another identifier in the SVG, in this case, the linear gradient
and
offset={`${Math.min(7, data.threshold)}%`}
min alone isn't a function, be sure to fully quantify it by calling Math.min
Code
<div className="flex flex-wrap -mx-2 mb-8">
{props.item.map((data, i) => (
<div
key={i}
className="w-full md:w-1/2 lg:w-1/4 px-2 mb-4 flex rounded justify-center items-center p-2 m-1"
>
<h1>abc</h1>
<svg
xmlns="http://www.w3.org/2000/svg"
width="100px"
height="140"
fill={`url(#color-${i})`}
viewBox="0 0 30 45"
aria-hidden="true"
style={{ transform: `translate(0, -20px)` }}
>
<defs>
<linearGradient
id={`color-${i}`}
x1="0%"
y1="100%"
x2="0%"
y2="0%"
>
<stop
offset={`${Math.min(7, data.threshold)}%`}
stop-color="rgb(40, 134, 248)"
/>
<stop
offset={`${data.humidity}%`}
stop-color="rgb(255, 0, 0)"
/>
<stop stop-color="rgb(227, 227, 227)" />
</linearGradient>
</defs>
<path
stroke="#2886f8"
d="M15 6
Q 15 6, 25 18
A 12.8 12.8 0 1 1 5 18
Q 15 6 15 6z"
/>
</svg>
</div>
))}
</div>
I am trying to decide what state management solution to choose. I don't think I need Redux yet, maybe Context API or local storage can do the trick or maybe another proposition. All I simply need is for the states of my tabs to be directly connected to their directed URL upon clicking on them, AND for the state to persist upon refreshing the page. Of course, that means that as long as the URL has a certain string that the state will update to the related value of the Tab, that would also secure the state value when a link directing the user to that URL is clicked on.
I hope I was clear enough, thank you for taking the time to read this.
Here are the imports:
import React from 'react';
import AppBar from '#material-ui/core/AppBar';
import CssBaseline from '#material-ui/core/CssBaseline';
import Drawer from '#material-ui/core/Drawer';
import Hidden from '#material-ui/core/Hidden';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import {withStyles } from '#material-ui/core/styles';
import SearchBar from '../TopBar/SearchBar'
import Home from '../Screens/Home'
import Contact from '../Screens/Contact'
import Profile from '../Screens/Profile'
import Settings from '../Screens/Settings'
import Messages from '../Screens/Messages'
import Products from '../Screens/Products'
import Tabs from "#material-ui/core/Tabs";
import Tab from "#material-ui/core/Tab";
import { Switch, Route, Link, BrowserRouter} from "react-router-dom";
Drawer variable holding the tab structure:
const drawer = (
<Route
path="/"
render={() => (
<nav>
<div style={{ left: 70, position: 'relative', marginTop: 40 }}>
<VerticalTabs
value={values}
variant="fullWidth"
onChange={this.handleChange}
>
<MyTab
component={Link}
to="/"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
version="1.1"
id="Capa_1"
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
width="460.298px"
height="460.297px"
viewBox="0 0 460.298 460.297"
space="preserve"
fill={values === 0 ? '#0D9DCE' : '#9B9B9B'}
className="home"
>
{homeA}
{homeB}
</svg>
}
label={
<p
className="home-Text"
style={{ color: values === 0 ? 'white' : '#9B9B9B' }}
>
Home
</p>
}
/>
<MyTab
component={Link}
to="/Screens/Contact"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
height="512pt"
viewBox="0 0 512 512"
width="512pt"
xmlns="http://www.w3.org/2000/svg"
fill={values === 1 ? '#0D9DCE' : '#9B9B9B'}
className="processes"
>
{ContactA}
</svg>
}
label={
<p
className="processes-Text"
style={{ color: values === 1 ? 'white' : '#9B9B9B' }}
>
Contact
</p>
}
/>
<MyTab
component={Link}
to="/Screens/Profile"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
version="1.1"
id="Capa_1"
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 512.001 512.001"
space="preserve"
className="designs"
fill={values === 2 ? '#0D9DCE' : '#9B9B9B'}
>
{ProfileA}
</svg>
}
label={
<p
className="designs-Text"
style={{ color: values === 2 ? 'white' : '#9B9B9B' }}
>
Profile
</p>
}
/>
<MyTab
component={Link}
to="/Screens/Settings"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
version="1.1"
id="Capa_1"
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 512 512"
space="preserve"
className="materials"
fill={values === 3 ? '#0D9DCE' : '#9B9B9B'}
>
{SettingsA}
{SettingsB}
</svg>
}
label={
<p
className="materials-Text"
style={{ color: values === 3 ? 'white' : '#9B9B9B' }}
>
Settings
</p>
}
/>
<MyTab
component={Link}
to="/Screens/Messages"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
width="512"
height="512"
viewBox="0 0 60 60"
version="1.1"
className="printers"
fill={values === 4 ? '#0D9DCE' : '#9B9B9B'}
>
{MessagesA}
{MessagesB}
{MessagesC}
{MessagesD}
{MessagesE}
{MessagesF}
</svg>
}
label={
<p
className="printers-Text"
style={{ color: values === 4 ? 'white' : '#9B9B9B' }}
>
Messages
</p>
}
/>
<MyTab
component={Link}
to="/Screens/Products"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
height="512pt"
viewBox="0 0 512 512"
width="512pt"
xmlns="http://www.w3.org/2000/svg"
className="forum"
fill={values === 5 ? '#0D9DCE' : '#9B9B9B'}
>
{ProductsA}
{ProductsB}
{ProductsC}
</svg>
}
label={
<p
className="QA-Text"
style={{ color: values === 5 ? 'white' : '#9B9B9B' }}
>
Products
</p>
}
/>
</VerticalTabs>
</div>
</nav>
)}
/>
);
Here is the routing structure within BrowserRouter:
<Switch>
<Route path="/Screens/Contact" component{Contact} />
<Route path="/Screens/Profile" component={Profile} />
<Route path="/Screens/Settings" component={Settings} />
<Route path="/Screens/Messages" component={Messages} />
<Route path="/Screens/Products" component={Products} />
<Route path="/" component={Home} />
</Switch>