I'm pretty new to react, and I am trying to make an Increment and decrement component in in my product screen. The issue that I'm having is that I would like it to only be able to increment if the there are that many items in stock, but when I try to do this the component stops showing the number associated with amount of the item chosen. I would really appreciate any help or guidance on how to do this.
Thank you!
ProductScreen.js
import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { detailsProduct } from '../actions/productActions';
import LoadingBox from '../components/LoadingBox';
import MessageBox from '../components/MessageBox';
import { IconContext } from 'react-icons';
import { FiPlus, FiMinus } from 'react-icons/fi';
export default function ProductScreen(props) {
const dispatch = useDispatch();
const productId = props.match.params.id;
const [qty, setQty] = useState(1);
const productDetails = useSelector((state) => state.productDetails);
const { loading, error, product } = productDetails;
const handleQuantity = (type) => {
if (type === "dec") {
qty > 1 && setQty(qty - 1);
}else if(product.countInStock >= product.qty){
setQty(qty + 1);
}
};
return (
<div>
{loading ? (
<LoadingBox></LoadingBox>
) : error ? (
<MessageBox variant="danger">{error}</MessageBox>
) : (
<div>
<Link to="/body">Back to result</Link>
<div className="row top">
<div className="col-1">
<div className="card card-body">
<ul>
<li>
<div className="row">
<div>Status</div>
<div>
{product.countInStock > 0 ? (
<span className="success">In Stock</span>
) : (
<span className="danger">Unavailable</span>
)}
</div>
</div>
</li>
{product.countInStock > 0 && (
<>
<li>
<div className="row">
<div>Qty</div>
<div className="AddContainer">
<div className="AmountContainer">
<FiMinus onClick={() => handleQuantity("dec")}/>
<div className="Amount">{product.qty}</div>
<FiPlus onClick={() => handleQuantity("inc")}/>
</div>
</div>
<div>
</div>
</div>
</li>
</>
)}
</ul>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
);
}
Related
build this part of the code with useState initially and everything worked perfectly but I need to share this state with my main component (no relationships between those two) and decided to use Redux but def something is wrong, any ideas?
Here's the console error:
MUI: The value provided to the Tabs component is invalid.
None of the Tabs' children match with "-1".
You can provide one of the following values: 0, 1, 2.
import { React } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import '../../css/SideBar.css';
import { UilSignOutAlt } from '#iconscout/react-unicons';
import Logo from '../../../../assets/img/companyLogo.jpg';
import { SidebarData } from '../../Data/Data';
import { setDashboard } from '../../../../app/actions';
function SideBar() {
const selected = useSelector((state) => state.dashboard);
const dispatch = useDispatch();
return (
<div className="Sidebar">
{/* logo */}
<div className="logo">
<img src={Logo} alt="logo" />
<span>Company Name</span>
</div>
{/* menu */}
<div className="menu">
{SidebarData.map((item, index) => (
/* eslint-disable */
<div
role='menu'
className={selected === index ? 'menuItem active' : 'menuItem'}
key={index}
onClick={() => dispatch(setDashboard(index))}
onKeyDown={() => dispatch(setDashboard(index))}
>
<item.icon />
<span>{item.heading}</span>
</div>
))}
<div className='menuItem'>
<UilSignOutAlt />
</div>
</div>
</div>
);
}
export default SideBar;
I'm having a problem that I can't solve. I have a component that is currently rendering the users that are in my database, which calls CarouselUsers.jsx, so far so good, it is showing correctly.
But my goal is that after I click on one of these users that were listed, his name appears in a sidebar, which is in another component, but I am not able to do that, can you help me?
CarouselUsers.jsx
import React, { useState, useEffect } from 'react';
import * as Styled from './style.jsx';
import {
collection,
getDocs,
} from "firebase/firestore";
import { Swiper, SwiperSlide } from "swiper/react";
import { db } from '../../Data/Firebase.jsx';
import "swiper/css";
import euTeste from '../../assets/teste.jfif'
import SideBarProfile from '../../components/SideBarProfile/SideBarProfile.jsx';
export default function CarouselUsers() {
const [profile, setProfile] = useState(false)
const openProfile = () => {
setProfile(profile => !profile)
}
// USERS IN THE DB
const [users, setUsers] = useState([])
const usersCollectionRef = collection(db, "usuarios")
useEffect(() => {
const getUsers = async () => {
const data = await getDocs(usersCollectionRef);
setUsers(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
};
getUsers();
}, []);
// USERS IN THE DB
return (
<>
<Styled.CarouselUsers>
{/* MEMBROS CARROSEL */}
<div className="boxMembros">
<div className="titulo">
<h6>Membros</h6>
</div>
<Swiper
spaceBetween={10}
slidesPerView={3}
>
{users.map((user) => {
return (
<>
<SwiperSlide>
<div className="box"style={{ background: `linear-gradient(to bottom,rgba(0, 0, 0, 0.4) 0,rgba(0,0,0,.6) 100%),url(${euTeste})` }} onClick={openProfile} key={user.nome}>
<div className="infoBottom">
<div className="info">
{/* GET THE USERNAME */}
<h6>{user.nome}</h6>
{/* GET THE USERNAME */}
</div>
</div>
</div>
</SwiperSlide>
</>
);
})}
</Swiper>
</div>
{/* MEMBROS CARROSEL */}
</Styled.CarouselUsers>
<SideBarProfile profile={profile} openProfile={openProfile} />
</>
)
}
SideBarProfile.jsx
import React from 'react'
import { XCircle,WhatsappLogo } from "phosphor-react";
import * as Styled from './style.jsx';
export default function SideBarProfile({openProfile,profile}) {
return (
<Styled.SideBarProfile>
<div className={profile ? 'col-md-3 boxLeftWrapper open' : 'col-md-3 boxLeftWrapper close'} profile={profile}>
<div className="boxAll">
<div className="header d-flex justify-between align-items-center">
<div className="titulo">
<h1>Perfil</h1>
</div>
<div className="close">
<button onClick={openProfile}>
<XCircle/>
</button>
</div>
</div>
<div className="boxBodyUser text-left">
<div className="boxThis">
<div className="foto">
<img alt="Usuário" className='img-fluid ativo' />
</div>
<div className="nome text-center">
<h5>{/* SHOW USERNAME */}</h5>
</div>
<div className="status ativo">
<span>Ativo</span>
</div>
<div className="ministerios">
<ul className="pl-0 list-none mb-0">
<li>Teatro</li>
<li>Mídias Sociais</li>
</ul>
</div>
<div className="boxContato mt-5">
<div className="whatsapp d-flex items-center justify-center gap-2">
<WhatsappLogo/>
<span>Mensagem</span>
</div>
</div>
</div>
</div>
</div>
</div>
</Styled.SideBarProfile>
)
}
You can add an onClick event in your CarouselUsers component that grab the Inner Text in <h6>{user.nome}</h6> and pass it as props to SideBarProfile component .
like this :
CarouselUsers.jsx :
export default function CarouselUsers() {
const [profile, setProfile] = useState(false)
const [selectedUser, setSelectedUser] = useState("")
const handleClick = (event) => {
setSelectedUser(event.target.innerText);
}
// rest of your code
return (
......
{/* GET THE USERNAME */}
<h6 onClick={handleClick} >{user.nome}</h6>
{/* GET THE USERNAME */}
.... rest of your code
<SideBarProfile profile={profile} openProfile={openProfile}
setSelectedUser = {setSelectedUser} />
)
}
SideBarProfile.jsx :
export default function SideBarProfile({openProfile,profile, setSelectedUser}) {
return (
......
<div className="nome text-center">
<h5>{setSelectedUser}</h5>
</div>
....
)
I'm building a website with React and Bootstrap which would have a static footer. The footer will contain two buttons - Back, and Next. Clicking 'back' decrements an index, and clicking 'next' would increment the index. Ideally this index would keep track of which js component to show or hide using a ternary statement with with display: 'inline' or 'none'. I've tried useState in the App.js file, AND in the Footer.js file, but I am unable to pass the useState values between components it seems. Is there a better way to do this? I have provided some of my code which does not work.
Footer.js:
import React from "react";
import { useState } from "react";
const Footer = (props) => {
const [pageIndex, setPageIndex] = useState(0);
return (
<div className="container-lg">
<div class="row justify-content-between mt-5">
<button
onClick={setPageIndex(pageIndex - 1)}
>
Back
</button>
<button
onClick={setPageIndex(pageIndex + 1)}
>
Next
</button>
</div>
</div>
);
};
export default Footer;
App.js:
function App() {
return (
<div className="App">
<div style={{display: Footer.pageIndex === 0 ? 'inline' : 'none'}}>
<Component />
</div>
<div style={{display: Footer.pageIndex === 1 ? 'inline' : 'none'}}>
<AnotherComponent />
</div>
<Footer />
</div>
);
}
export default App;
Few issues with your code: 1) className, not the class in react. 2) Error in your onClick parameters. 3) You need to move state up to the App component.
const {useState} = React;
function App() {
const [pageIndex, setPageIndex] = useState(0);
return (
<div className="App">
<div style={{ display: pageIndex === 0 ? "inline" : "none" }}>
<Component />
</div>
<div style={{ display: pageIndex === 1 ? "inline" : "none" }}>
<AnotherComponent />
</div>
<Footer setPageIndex={setPageIndex} />
</div>
);
}
const Footer = ({ setPageIndex }) => {
return (
<div className="container-lg">
<div className="row justify-content-between mt-5">
<button onClick={() => setPageIndex((prev) => prev - 1)}>Back</button>
<button onClick={() => setPageIndex((prev) => prev + 1)}>Next</button>
</div>
</div>
);
};
const Component = (props) => {
return <p>Component</p>;
};
const AnotherComponent = (props) => {
return <p>AnotherComponent</p>;
};
ReactDOM.createRoot(
document.getElementById("root")
).render(
<App />
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
<div id="root"></div>
Shift the state of the footer to be at the parent which is App.js
import React from "react";
import { useState } from "react";
const Footer = (props) => {
const { setPageIndex, pageIndex } = props;
return (
<div className="container-lg">
<div class="row justify-content-between mt-5">
<button onClick={()=> setPageIndex(pageIndex - 1)}>Back</button>
<button onClick={()=> setPageIndex(pageIndex + 1)}>Next</button>
</div>
</div>
);
};
export default Footer;
and then you could pass the setPageIndex as prop to the footer.
function App() {
const [pageIndex, setPageIndex] = useState(0);
return (
<div className="App">
<div style={{ display: Footer.pageIndex === 0 ? "inline" : "none" }}>
<Component />
</div>
<div style={{ display: Footer.pageIndex === 1 ? "inline" : "none" }}>
<AnotherComponent />
</div>
<Footer setPageIndex={setPageIndex} pageIndex={pageIndex} />
</div>
);
}
export default App;
I tell you that I am making a shopping cart and I get the following warning "Functions are not valid as a React child. This can happen if you return a Component instead of from render. Or maybe you meant to call this function instead of returning it.", what I am doing is passing through an event information to the father from the son to be used later in the Cart.
the codes are these:
ItemDetial (detail of the product selected by the customer):
import React, { useState } from "react";
import '../App.css';
import 'materialize-css/dist/css/materialize.css';
import Count from './ItemCount';
import { Link } from "react-router-dom";
export const ItemDetail = (({item}) => {
const [itemSell, setItemSell] = useState(false);
const onAdd = (count) => {
setItemSell(true);
}
return (
<>
{
<main className="row soloProduct" id= {item.id}>
<aside>
<img src={item.image} alt="item" className="itemImg responsive-img"/>
</aside>
<article>
<div className=" col s12 m8">
<h5 className="itemName">{item.title}</h5>
</div>
<div className="col s12 m4">
<p className="itemPrice"> {item.price}</p>
</div>
<div className="col s12 m12">
<p className="itemDescription">{item.description}</p>
</div>
<div className="col s12">
{
itemSell ? <Link to="/cart"><button className="waves-effect waves-light btn-large">Finalizar Compra</button></Link> : <Count stockInitial={5} onAdd= { onAdd } />
}
</div>
</article>
</main>
}
</>
)
});
export default ItemDetail;
ItemCount (it is a counter so that the client has the possibility of buying more than one product):
import React, { useState} from 'react';
import 'materialize-css/dist/css/materialize.css';
import '../App.css';
import {FontAwesomeIcon} from '#fortawesome/react-fontawesome';
import {faPlus, faMinus, faPowerOff} from '#fortawesome/free-solid-svg-icons';
const ItemCount = ({stockInitial, initial = 0, onAdd}) => {
const [contador, setContador] = useState(initial)
const [stock, setStock] = useState(stockInitial)
const sumar = () => {
setContador(contador + 1)
setStock(stock - 1);
avisarStock();
}
const restar= () => {
if(contador > 0){
setContador(contador - 1);
setStock(stock + 1);
}
else
{
setContador(0);
}
}
const reset = () =>{
setContador(0);
setStock(stockInitial);
}
const avisarStock = () => {
if(stock > 0 ){
}
else{
alert('No podemos enviar su envio no hay stock');
setStock(0);
setContador(contador)
}
}
const agregarAlCarrito = () => {
onAdd(contador);
}
return(
<>
<div className=" row left text">Stock: {stock}</div>
<article>{contador}</article>
<div className="buttonCount">
<button onClick={sumar}>
<FontAwesomeIcon icon ={faPlus}/>
</button>
<button onClick={restar}>
<FontAwesomeIcon icon={faMinus}/>
</button>
<button onClick={reset}>
<FontAwesomeIcon icon={faPowerOff}/>
</button>
<br/><h2>{avisarStock}</h2>
<button onClick={agregarAlCarrito}> Agregar al carrito </button>
</div>
</>
)
}
export default ItemCount;
if you can give me a hand
Thank you
Hey juan hope you're doing well..
I just found a single mistake that is your ( brackets in itemdetails component. check the same your code given below-
import React, { useState } from "react";
import '../App.css';
import 'materialize-css/dist/css/materialize.css';
import Count from './ItemCount';
import { Link } from "react-router-dom";
const ItemDetail = ({item}) => {
const [itemSell, setItemSell] = useState(false);
const onAdd = (count) => {
setItemSell(true);
}
return (
<>
{
<main className="row soloProduct" id= {item.id}>
<aside>
<img src={item.image} alt="item" className="itemImg responsive-img"/>
</aside>
<article>
<div className=" col s12 m8">
<h5 className="itemName">{item.title}</h5>
</div>
<div className="col s12 m4">
<p className="itemPrice"> {item.price}</p>
</div>
<div className="col s12 m12">
<p className="itemDescription">{item.description}</p>
</div>
<div className="col s12">
{
itemSell ? <Link to="/cart"><button className="waves-effect waves-light btn-large">Finalizar Compra</button></Link> : <Count stockInitial={5} onAdd= { onAdd } />
}
</div>
</article>
</main>
}
</>
)
};
export default ItemDetail;
If this works just lemme know. thanks
I'm trying to delete multiple items at once for checkboxes in REACT, but the code does not seem to delete the items being checked.
Here's my approach to doing this. I made a function in tasks.jsx file
called add_ids_to_be_deleted to append the id that was being checked
in the checkbox to an array of ids to be deleted called list_of_ids.
This function is called in the child component in priorityLists.jsx.
When the user clicks the delete button, I created a useEffect to
filter out all the items in toDo whose ids are not included in the ids
to be deleted.
The problem is it keeps deleting the last item whenever I check a checkbox regardless of the order.
For example, I add 3 checkboxes and
check the first checkbox to delete it. Instead of the first checkbox
being deleted, the last item is deleted even though it wasn't being
checked.
tasks.jsx
import React, { useState, useEffect } from 'react';
import { Delete, Refresh, Add } from '../components/Actions';
import { Header } from '../components/Header';
import ToDoList from '../components/TaskList';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faPlus, faTrash } from '#fortawesome/free-solid-svg-icons';
import { v4 as uuidv4 } from 'uuid';
function Task() {
const [toDo, setToDo] = useState([]);
const [idsToRefresh, setIdsToRefresh] = useState([]);
const [list_of_Ids, setIds] = useState([]);
const [filter_now, setFilterNow] = useState(false);
function addToDos() {
const id = uuidv4();
setToDo(
toDo.concat({
_isKey: id,
_checked: false,
value: <ToDoList _onDelete={add_Ids_ToBe_Deleted} _key={id} />
})
);
setIdsToRefresh(idsToRefresh.concat(id));
}
function switchNow() {
if (!filter_now) {
setFilterNow(true);
} else {
setFilterNow(false);
}
}
useEffect(() => {
if (toDo[0] !== undefined) {
setToDo(
toDo.filter(item => {
return !list_of_Ids.includes(item._isKey);
})
);
}
}, [filter_now]);
function add_Ids_ToBe_Deleted(_id_ToBe_Deleted) {
setIds(item => [...item, _id_ToBe_Deleted]);
}
function refresh() {
setToDo(
toDo.filter(item => {
return !idsToRefresh.includes(item._isKey);
})
);
}
return (
<div className="main-content">
<div className="container-fluid">
<div className="row underline">
<div className="col">
<div className="row">
<div className="col-3 pt-2">
<Refresh _refresh={refresh} />
</div>
<div className="col-6 text-center">
<Header header={'Tasks'} />
</div>
<div className="col-3 pt-2">
<button className="float-right">
<FontAwesomeIcon
onClick={switchNow}
icon={faTrash}
size="2x"
/>
</button>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col">
{toDo.map(item => {
return (
<div>
<ul>
<li>{item.value}</li>
</ul>
</div>
);
})}
</div>
</div>
<div className="row">
<div className="col pr-4">
<button onClick={addToDos} className="float-right" name="add">
<FontAwesomeIcon icon={faPlus} size="2x" />
</button>
</div>
</div>
</div>
</div>
);
}
export default Task;
Tasklist.jsx
import React from 'react';
import { PriorityLists } from '../components/PriorityLists';
import { Priority } from './Actions';
function ToDoList(props) {
return (
<PriorityLists
_onDelete={props._onDelete}
keys={props._key}
name="toDoList"
>
<Priority />
</PriorityLists>
);
}
export default ToDoList;
Prioritylists.jsx
import React, { useState, useEffect } from 'react';
import { Priority } from './Actions';
function PriorityLists(props) {
return (
<form>
<div className="input-group mb-3">
<div className="input-group-prepend">
<div className="input-group-text">
<input
is_checked={false}
unique_Key={props.keys}
onClick={e =>
props._onDelete(
e.target.attributes.getNamedItem('unique_Key').value
)
}
id="check-item"
type="checkbox"
aria-label="Checkbox for following text input"
/>
</div>
</div>
<textarea class="form-control" rows="1" name={props.name}></textarea>
{props.children}
</div>
</form>
);
}
export { PriorityLists };