ReactJS frustrating element.scrollTop bug - javascript

I have this frustrating problem with scroll in my ReactJS and TailwindCSS project. I was trying to show element when viewport is on specific part of my website and to hide it when it's not.
function App() {
const scrollRef = createRef()
const [isVisible, setIsVisible] = useState(false);
const handleScroll = () => {
let heightToShow = 1000;
const winScroll = document.querySelector('.App').scrollTop;
if (winScroll > heightToShow) {
setIsVisible(true);
} else {
setIsVisible(false);
}
};
return (
<div onScroll={handleScroll} className="App scroll-smooth relative bg-secondary h-screen snap-y snap-mandatory overflow-x-hidden overflow-y-scroll flex flex-col">
<div ref={scrollRef} />
<Header />
<About />
<Skills />
<Projects />
<Contacts />
<TopButton isVisible={isVisible} ref={scrollRef} />
</div>
);
}
export default App;
At first, i've tried using window.pageYOffset which didn't work, because the value always stayed at 0 and element didn't show up. With document.querySelector('.App').scrollTop I made the functionality work as needed, but I got this terrible bug, where if winScroll's value gets to heightToShow's value - my viewport jumps back to the original winScroll's value. So basically, It is almost impossible to scroll both ways with mousewheel past my heightToShow value.
Any thoughts on why it is happening?

Related

How to slide with my finger on mobile the same way the pointer does on desktop?

I am working on a StarRating component in React where people can select their rating from 1-5 stars. It works well on desktop where I can hover over the stars and it changes colors responsively.
gif of working desktop StarRating
I am using onPointerEnter and onPointerLeave to set the Hover state. I would assume this would work for mobile too, however when I slide my finger across the stars it doesn't change the color because everytime it does onPointerLeave it won't activate onPointerEnter unless I lift my finger and put it back down on another star.
Here is my code.
const StarRating = () => {
const [rating, setRating] = useState(null);
const [hover, setHover] = useState(null);
return (
<div className="flex items-center justify-center">
{[...Array(5)].map((star, i)=> {
const ratingValue = i+1;
return (
<label key={i}>
<input
type='radio'
name='rating'
className="invisible"
value={ratingValue}
onClick={e => setRating(ratingValue)}
/>
<StarIcon
id="star"
color={ratingValue <= (hover || rating) ? "gold" : "#e5e7eb" }
fill={ratingValue <= (hover || rating) ? "gold" : "#e5e7eb" }
width={50}
className='cursor cursor-pointer touch-auto ease-in duration-200'
onPointerEnter={(e)=>{setHover(ratingValue)}
onPointerLeave={(e)=>{setHover(null)}}
/>
</label>
)
})}
</div>
);
};
export default StarRating;
It seems like releasePointerCapture may be what I need, however I can't get it to work with how I have my component set up in react.
Any advice would be much appreciated.

TailwindCSS overflow-auto class not working with React Lists

I am experiencing an issue where the overflow properties of Tailwind are not working with react lists. I am wondering if this is just a simple mistake on my part or if there is a work around that I need to do.
Image to It Not Working
import CoinSummary from './CoinSummary'
const Holdings = ({ coins }) => {
return (
<div className='overflow-auto p-4'>
<h2 className='text-2xl text-center font-bold mt-4'>Holdings</h2>
{coins &&
coins.map((coin, index) => {
return <CoinSummary key={index} coin={coin} />
})}
</div>
)
}
export default Holdings
I want the list of coins to stay inside of the Holdings component and if it overflows, to have a scroll bar instead. However, as you can see in the photo, it doesn't seem to be working like I expected it to.
I was able to figure it out on my own. It was because I did not specify the height to be h-full

optimize onScroll event in React

I have a simple horizontal scroll div.
function Horizontal(){
const [now, setNow] = React.useState(0);
function handleScroll(e){
const { scrollLeft } = e.currentTarget;
setNow(scrollLeft);
}
return (
<>
<p>{now}px</p>
<div width={3000} height={80} onScroll={handleScroll}>
{...}
</div>
</>
)
}
This is an example code and it works well.
but I realize scrollLeft causes reflow.
so, I want to optimize it as well as possible.
Please leave advice if you have any.

How to check if a div overflow the page in React?

I have a div whose height can sometimes overflow the page's height because of a long content. How to know if it is the case? I tried to compare scrollHeight to clientHeight, but both values are the same. Here is the code:
const Component = ({text}) => {
const ref = React.useRef(null);
const contentOverflowPage = ref.current && ref.current.scrollHeight > ref.current.clientHeight
return (
<Root ref={ref}>
{content}
</Root>
);
};
export default Component;
How to fix this? Thanks!

React Media Query needs refresh to show image

I am using react-media (https://github.com/ReactTraining/react-media) to handle different screen sizes. The aim of using react-media: Just bigger screens should see the parallax image (using materializeCSS for parallax). Problem:
If you resize the window, the image will disappear (how it should be) and when you go back to the bigger screen the place of the image is white. After refreshing the page the image is there again. I noticed it occurs every time when I use media and a javascript materializeCSS "package". How can I fix that?
import React, { useLayoutEffect } from "react";
import picture from "../../image/Introduction.jpeg";
import Media from "react-media";
const Paralaxes = () => {
useLayoutEffect(() => {
const M = window.M;
const elems = document.querySelectorAll(".parallax");
M.Parallax.init(elems, {});
});
return (
<Media query={{ minWidth: 768 }}>
{matches =>
matches ? (
<div className="parallax-container">
<div className="parallax">
<img src={picture} className="responsive-img" alt="background" />
</div>
</div>
) : (
<div className="container">
<div className="divider black" />
</div>
)
}
</Media>
);
};
export default Paralaxes;
Thanks a lot!

Categories