**Hello, I'm having a problem with react-horizontal-scrolling-menu
, when scrolling, it scrolls to the right a lot, and the rest of the elements disappear, and when you add overflowX: 'scroll' to the BOX, the scroll doesn't work until after the first click
Plus LeftArrow, RightArrow don't work
Take a look at the code**
[error img here]
<Box component="div" sx={{position:'relative', width:'100%',p:'20px'}}>
<HorizontalScrollbar data={bodyParts} bodyParts={bodyParts} bodyPart={bodyPart} setBodyPart={setBodyPart}/>
</Box>
HorizontalScrollba
import React, { useContext } from 'react';
import { ScrollMenu, VisibilityContext } from 'react-horizontal-scrolling-menu';
import { Box, Typography } from '#mui/material';
import BodyPart from './BodyPart';
import RightArrowIcon from '../assets/icons/right-arrow.png';
import LeftArrowIcon from '../assets/icons/left-arrow.png';
const LeftArrow = () => {
const { scrollPrev } = useContext(VisibilityContext);
return (
<Typography onClick={() => scrollPrev()} className="right-arrow">
<img src={LeftArrowIcon} alt="right-arrow" />
</Typography>
);
};
const RightArrow = () => {
const { scrollNext } = useContext(VisibilityContext);
return (
<Typography onClick={() => scrollNext()} className="left-arrow" >
<img src={RightArrowIcon} alt="right-arrow"/>
</Typography>
);
};
const HorizontalScrollbar = ({ data, bodyParts, setBodyPart, bodyPart }) => (
<Box mt={4} sx={{position:'static'}}>
<ScrollMenu LeftArrow={LeftArrow} RightArrow={RightArrow}>
{data.map((item) => (
<Box
key={item.id || item}
itemId={item.id || item}
title={item.id || item}
m="0 40px"
>
<BodyPart item={item} setBodyPart={setBodyPart} bodyPart={bodyPart} />
</Box>
))}
</ScrollMenu>
</Box>
);
export default HorizontalScrollbar;
install npm i react-horizontal-scrolling-menu#2.7.1, the latest 3.0.1 version has some issues regarding overflow
I was also stuck here but I did a little hack to move on like I just copied the package.json from the git(link was mentioned in the description) and run the command 'npm install' and it start working.
I suggest you also do the same so you can move and after the installation look for an error or the problem
Happy Learning
use Button rather than Typography :
const LeftArrow = () => {
const { scrollPrev } = useContext(VisibilityContext);
return (
<Button onClick={() => scrollPrev()} className="right-arrow">
<img src={LeftArrowIcon} alt="right-arrow" />
</Button>
);
};
This works as intended.
Related
I have a code with which the user can select a file from their device. The Card component will display its name and operations that can be done with the file.
But my problem is that I don't know how to close this component if the user wants to cancel the action.
export default function DisplaySelectedFile() {
const [fileName, setFileName] = useState("");
console.log(setFileName)
return (
<div>
<SelectFileButton setFileName={setFileName} />
{fileName && <Card sx={styles.CommonStyle}>
<Stack spacing={10} direction="row" style={{paddingTop: "20px", paddingLeft: "10px"}}>
<div>{fileName}</div>
<Stack spacing={3} direction="row">
<div>Convert to</div>
<ConvertToFormatFile></ConvertToFormatFile>
</Stack>
<Button>CONVERT</Button>
<CloseIcon/>
</Stack>
</Card>}
</div>
);
}
I have added a button which should close the entire Card component. If I add the following code
<CloseIcon onClick={() => setFileName(false)}/>
If I add the following code, then the component closes. But the next time you select a file, this component does not open (only after reloading the page).
Tell me how to close the Card component correctly so that you can open it without problems
I would suggest to handle separately the card visibility and the file name value.
Something like this should work:
import React, { useState, useCallback } from "react";
const DisplaySelectedFile = () => {
const [fileName, setFileName] = useState(null);
const [showCard, setShowCard] = useState(false);
const handleSelectFile = useCallback(
(file) => {
setFileName(file);
file && setShowCard(true);
},
[setFileName, setShowCard]
);
const handleCloseCard = useCallback(() => {
setShowCard(false);
setFileName(null); // add this line only if it fits your use case
}, [setFileName, setShowCard]);
return (
<div>
<SelectFileButton setFileName={handleSelectFile} />
{showCard && (
<Card sx={styles.CommonStyle}>
<Stack
spacing={10}
direction="row"
style={{ paddingTop: "20px", paddingLeft: "10px" }}
>
<div>{fileName}</div>
<Stack spacing={3} direction="row">
<div>Convert to</div>
<ConvertToFormatFile></ConvertToFormatFile>
</Stack>
<Button>CONVERT</Button>
<CloseIcon onClick={handleCloseCard} />
</Stack>
</Card>
) || null}
</div>
);
}
export default DisplaySelectedFile;
Im having problem displaying the total amount of items in the cart. The cart itself loads without a problem and items are also added without a problem. But when I try to get the total amount of items in the cart totalItems = {cart.total_items} and pass it on to the navbar.jsx file to be displayed, I get many errors. The app.js file is as follows:
import React, { useState, useEffect } from 'react';
import { commerce } from './lib/commerce';
import { Products, Navbar } from './components';
const App = () => {
const [products, setProducts] = useState([]);
const [cart, setCart] = useState({});
const fetchProducts = async () => {
const { data } = await commerce.products.list();
setProducts(data);
};
const fetchCart = async () => {
setCart(await commerce.cart.retrieve());
};
const handleAddToCart = async (productId, quantity) => {
const item = await commerce.cart.add(productId, quantity);
setCart(item.cart);
}
useEffect(() => {
fetchProducts();
fetchCart();
}, []);
console.log(cart);
return (
<div>
<Navbar totalItems={cart.total_items} />
<Products products={products} onAddToCart={handleAddToCart} />
</div>
)
};
export default App;
The main errors I get are: "Uncaught Error: Objects are not valid as a React child (found: object with keys {totalItems}). If you meant to render a collection of children, use an array instead." and "The above error occurred in the component:". Im very new to react.js so any help would be appreciated.
Navbar.jsx code is as follows:
import React from 'react';
import { AppBar, Toolbar, IconButton, Badge, MenuItem, Menu, Typography } from '#material-ui/core';
import { ShoppingCart } from '#material-ui/icons';
import logo from '../../assets/mainlogo.png';
import useStyles from './styles';
const navbar = ({ totalItems }) => {
const classes = useStyles;
return (
<>
<AppBar position="fixed" className={classes.appBar} color="inherit">
<Toolbar>
<Typography variant="h6" className={classes.title} color="inherit">
<img src={logo} alt="Commerce.js" height="25px" className={classes.image} />
Project
</Typography>
<div className={classes.grow} />
<div className={classes.button}>
<IconButton aria-label="Show cart items" color="inherit">
<Badge overlap="rectangular" badgeContent={totalItems} color="secondary">
<ShoppingCart/>
</Badge>
</IconButton>
</div>
</Toolbar>
</AppBar>
</>
)
}
export default navbar
i believe we are working on the same project from youtube ,i also encountered this problem.
u should try adding ? after the item then adding .cart
setMyCart(item?.cart)
or you can just ignore the .cart it will work just fine.
every-time you face this undefined error you should work around it with ? or ternary such as this example:
if (!myCart.line_items) return 'Loading...' return (
<Container>
<div className={classes.toolbar} />
<Typography className={classes.title} variant="h3" gutterBottom>
Your Shopping Cart
</Typography>
{!myCart.line_items.length ? <EmptyCart /> : <FilledCart />}
</Container> ) }
I get this error while adding a functionality to my web app.
-> so basically there are a few cards on the map and if user 'click' any of the one, the app will scroll to description of that particular card.
And I suppose the error [Violation] 'requestAnimationFrame' handler took 136ms is coming from the following code
const PlaceDetails = ({ place, selected, refProp }) => {
// console.log(place);
const classes = useStyles();
if (selected)
refProp?.current?.scrollIntoView({ behavior: "smooth", block: "start" });
return (
<Card elevation={6}>
<CardMedia
...
map.jsx
return (
<div className={classes.mapContainer}>
<GoogleMapReact
bootstrapURLKeys={{ key: process.env.REACT_APP_GOOGLE_MAPS_API_KEY }}
// get key from https://console.cloud.google.com/
defaultCenter={coordinates}
center={coordinates}
defaultZoom={14}
margin={[50, 50, 50, 50]}
options={""}
onChange={(e) => {
// console.log(e);
setCoordinates({ lat: e.center.lat, lng: e.center.lng });
setBounds({ ne: e.marginBounds.ne, sw: e.marginBounds.sw });
}}
// as we click a child (card) we want information about which child was the click from the map component all the way to the list component
onChildClick={(child) => setChildClicked(child)}
>
{places?.map((place, i) => (
<div
className={classes.markerContainer}
lat={Number(place?.latitude)}
lng={Number(place?.longitude)}
key={i}
>
List.js
import React, { useState, useEffect, createRef } from "react";
import {
CircularProgress,
Grid,
Typography,
InputLabel,
MenuItem,
FormControl,
Select,
} from "#material-ui/core";
import PlaceDetails from "../PlaceDetails/PlaceDetails";
import useStyles from "./styles";
const List = ({ places, childClicked, isLoading }) => {
const classes = useStyles();
const [type, setType] = useState("restaurants");
const [rating, setRating] = useState("");
const [elRefs, setElRefs] = useState([]);
// console.log({ places });
useEffect(() => {
const refs = Array(places?.length)
.fill()
.map((_, i) => elRefs[i] || createRef());
setElRefs(refs);
}, [places]);
return (
<div className={classes.container}>
{isLoading ? (
<div className={classes.loading}>
<CircularProgress size="5rem" />
</div>
) : (
<>
// ... other code
<Grid container spacing={3} className={classes.list}>
{places?.map((place, i) => (
<Grid item key={i} xs={12}>
<PlaceDetails
place={place}
selected={Number(childClicked) === i}
refProp={elRefs[i]}
/>
</Grid>
))}
</Grid>
</>
)}
</div>
);
};
export default List;
could somebody help me in understanding why the scroll is not working and what error chrome consoles is showing me.
I am trying to trigger the Redirect React Dom
that is my button component in the handleMenuItemClick() function. But nothing happens.
I have tried a bunch of stuff but but still no success.
How can I make the both work together? My best try was to make a function that return the Redirect component as I saw in one post around, but still no success.
My Code:
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { Grid, Button, ButtonGroup, ArrowDropDownIcon, ClickAwayListener, Grow, Paper, Popper, MenuItem, MenuList, Link } from '#material-ui/core/Grid';
const SplitButton = (props) => {
const [open, setOpen] = React.useState(false);
const anchorRef = React.useRef(null);
const [selectedIndex, setSelectedIndex] = React.useState(1);
const myGroups = props.myGroups
const handleMenuItemClick = (event, index) => {
setSelectedIndex(index);
setOpen(false);
return <Redirect to={`/groups/${index}`} />
};
const handleToggle = () => {
setOpen((prevOpen) => !prevOpen);
};
const handleClose = (event) => {
if (anchorRef.current && anchorRef.current.contains(event.target)) {
return;
}
setOpen(false);
};
return (
<>
<ButtonGroup variant="contained" color="primary" ref={anchorRef} aria-label="split button">
<Button onClick={null}>My Groups</Button>
<Button
color="primary"
size="small"
aria-controls={open ? 'split-button-menu' : undefined}
aria-expanded={open ? 'true' : undefined}
aria-label="select merge strategy"
aria-haspopup="menu"
onClick={handleToggle}
>
<ArrowDropDownIcon />
</Button>
</ButtonGroup>
<Popper open={open} anchorEl={anchorRef.current} role={undefined} transition disablePortal>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{
transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom',
}}
>
<Paper>
<ClickAwayListener onClickAway={handleClose}>
<MenuList id="split-button-menu">
{ myGroups.map((group) => (
<MenuItem
key={group.id}
onClick={(event) => handleMenuItemClick(event, group.id)}
>
{group.title}
</MenuItem>
))}
</MenuList>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</>
);
}
export default SplitButton
You can redirect user via 2 methods: useHistory or <Redirect />
useHistory hook
If you want to redirect the user directly on click, you can treat the code imperatively and tell React what to do:
const history = useHistory();
const handleMenuItemClick = (event, index) => {
setSelectedIndex(index);
setOpen(false);
history.push(`/groups/${index}`)
};
More info https://reactrouter.com/web/api/Hooks/usehistory
Redirect component
Or if you feel more comfortable using React's default declarative model, you can say what's changed and allow your code to react to this change:
const [redirectUrl, setRedirectUrl] = useState('')
const handleMenuItemClick = (event, index) => {
setSelectedIndex(index);
setOpen(false);
setRedirectUrl(`/groups/${index}`)
};
if (redirectUrl) {
return <Redirect to={redirectUrl} />
}
return (
<>
<ButtonGroup variant="contained" color="primary" ref={anchorRef} aria-label="split button">
<Button onClick={null}>My Groups</Button>
<Button
...
More info https://reactrouter.com/web/api/Redirect
Im working on a project where im creating swipe card effect and im getting failed to compile when running npm run start:dev on the app
import React from 'react';
import Cards, { Card } from 'react-swipe-card'
const data = ['Alexandre', 'Thomas', 'Lucien']
const SwipeCard = () => (
return (
<Cards onEnd={action('end')} className='master-root'>
{data.map(item =>
<Card
onSwipeLeft={action('swipe left')}
onSwipeRight={action('swipe right')}>
<h2>{item}</h2>
</Card>
)}
</Cards>
)
);
export default SwipeCard;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Doc can be found here
You are using an arrow function without a body for your SwipeCard component which has an implicit return, so you can just remove the return statement.
const SwipeCard = () => (
<Cards onEnd={action("end")} className="master-root">
{data.map(item => (
<Card
key={item}
onSwipeLeft={action("swipe left")}
onSwipeRight={action("swipe right")}
>
<h2>{item}</h2>
</Card>
))}
</Cards>
);
As mentioned by #Tholle you can simply remove the return statement. Alternatively you can change the outer ( and ) to { and } as shown below to imply a function. I generally do this to have a consistent format across all my arrow functions.
import React from 'react';
import Cards, { Card } from 'react-swipe-card'
const data = ['Alexandre', 'Thomas', 'Lucien']
const SwipeCard = () => {
return (
<Cards onEnd={action('end')} className='master-root'>
{data.map(item =>
<Card
onSwipeLeft={action('swipe left')}
onSwipeRight={action('swipe right')}>
<h2>{item}</h2>
</Card>
)}
</Cards>
)
};
export default SwipeCard;