How to scroll at bottom in react on button - javascript

I am trying to scroll down user at bottom when user click on button . I really tried hard but didn't find any solution . Could someone please help me how to achieve my goal .
Thanks

You can use document.body.offsetHeight to get the height of the page and scroll to it using windows.scroll. If you need to support IE11 and lower use window.scroll(0, document.body.offsetHeight);
import React from 'react';
function App() {
function handleScroll() {
window.scroll({
top: document.body.offsetHeight,
left: 0,
behavior: 'smooth',
});
}
return <button type="button" onClick={handleScroll}>Scroll</button>;
}

There are few ways to achieve this:
const onClick = () => {
window.scroll({
bottom: document.body.scrollHeight, // or document.scrollingElement || document.body
left: 0,
behavior: 'smooth'
});
}
...
return <button onClick={onClick} ... />
and another way with a ref. You need to add an element to the bottom of the page
and scroll to it after button clicked:
const bottomRef = React.useRef();
const onClick = () => {
bottomRef.current.scrollIntoView();
}
...
return (
<div className="container">
<button onClick={onClick} />
<div className="bottomContainerElement" ref={bottomRef} />
<div>
)

You install react-scroll-button npm package
npm i react-scroll-button
Usage code
import React, {Component} from 'react'
import ScrollButton from 'react-scroll-button'
class ScrollComponent extends Component {
render() {
return (
<ScrollButton
behavior={'smooth'}
buttonBackgroundColor={'red'}
iconType={'arrow-up'}
style= {{fontSize: '24px'}}
/>
);
}
}

You can use useRef hook to scrool to particular div.
This is the most recommended method by react and using react hooks.
App.js
import React, { useRef } from "react";
import "./styles.css";
export default function App() {
const divRef = useRef();
return (
<div className="App">
<button
onClick={() => {
divRef.current.scrollIntoView({ behavior: "smooth" });
}}
>
Scroll to Bottom
</button>
<div className="bigDiv" />
<div className="bigDiv" />
<div className="bigDiv" />
<div className="bigDiv" ref={divRef}>
Scrolled Here
</div>
</div>
);
}
Styles.css
.App {
font-family: sans-serif;
text-align: center;
}
.bigDiv {
height: 100vh;
width: 100%;
background: cyan;
border: 1px solid violet;
}

Related

I created a Modal using createPortal() method to render it. Then I found that modal renders twice

When the button inside the Post clicked, Popup will render with createPortal method outside from root element's tree.
With this code that popup renders twice.
I want to render it only once.
Here's the parent Post component.
import { useState } from 'react';
import PopupModal from './PopupModal/PopupModal';
import './Post.css';
const Post = (props) => {
const postData = props;
const [isOpen, setIsOpen] = useState(false);
return (
<div className="post-container">
<div className="post-img-container">
<img className="post-img" src={props.img} alt="Travels" />
</div>
<div className="post-text-container">
<h4 className="post-heading">{props.title}</h4>
<p className="post-para">{props.description}</p>
<h1 className="post-price">{props.price}</h1>
<div className="post-btn-container">
<button onClick={() => setIsOpen(true)} className="post-btn">
Check Availability
</button>
<PopupModal dataData={postData} open={isOpen} onClose={() => setIsOpen(false)}>
Button123
</PopupModal>
</div>
</div>
</div>
);
};
export default Post;
And here's the popupModal
import React from 'react';
import ReactDOM from 'react-dom';
import '../PopupModal/popupModal.css'
const MODAL_STYLES = {
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%,-50%)',
background: '#fff',
width: '40vw',
height: '90vh',
padding: '50px',
zIndex: 1000,
};
const PopupModal = ({ open, children, onClose ,dataData }) => {
if (!open) return null;
console.log('xxx');
console.log(dataData);
return ReactDOM.createPortal(
<>
<div className='modal-overlay' ></div>
<div className='modal-container'>
<button onClick={onClose}> Popup Close</button>
{children}
</div>
</>,
document.getElementById('portal')
);
};
export default PopupModal;
Here's how I figured it rendered twice.
Here's the Popup with overlay around it which covers the background.
Thanks in advance!
Try following
{
isOpen && <PopupModal dataData={postData} open={isOpen} onClose={() => setIsOpen(false)}>
Button123
</PopupModal>
}

making antd modal full screen without any padding or margins

I'm new to programming. Here I have an antd modal and I've been trying to find a way to make it full screen. I want the modal to be full scree when it's opened and it shouldn't have any margin or paddings. For example, in the code I added width={1000} but there is still some margin on the left and right of the modal.
So how do I make the modal to take the whole screen without any margin and padding?
code:
https://codesandbox.io/s/otjy6?file=/index.js:539-560
Remove the fixed value for modal width and the centered attribute from your code file:
index.js
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Modal, Button } from 'antd';
const App = () => {
const [visible, setVisible] = useState(false);
return (
<>
<Button type="primary" onClick={() => setVisible(true)}>
Open Modal of 1000px width
</Button>
<Modal
title="Modal 1000px width"
// This was removed
// centered
visible={visible}
onOk={() => setVisible(false)}
onCancel={() => setVisible(false)}
// This was removed
// width={'1000'}
>
<p>some contents...</p>
<p>some contents...</p>
<p>some contents...</p>
</Modal>
</>
);
};
ReactDOM.render(<App />, document.getElementById('container'));
You need to add these CSS rules to the CSS file.
index.css
.ant-modal, .ant-modal-content {
height: 100vh;
width: 100vw;
margin: 0;
top: 0;
}
.ant-modal-body {
height: calc(100vh - 110px);
}
you need to unset max-width and margin of modal
.ant-modal {
max-width: unset;
margin: unset;
}
you need to unset content in before pseudo-element of ant-modal-centered class
.ant-modal-centered::before {
content: unset;
}
Working Demo
I think instead of Modal you can use the Antd Drawer. Here is the implementation.
import React,{useState} from 'react';
import {Drawer} from 'antd;
const FullScreenDrawer = ()=>{
const [visible,setVisible] = useState(false)
return(
<>
<button onClick={()=>setVisible(true)/>
<Drawer
visible={isVisible}
onClose={() => setVisible(false)}
width="100VW"
>
The content goes here
</Drawer>
</>
);
}

How to efficiently toggle classes with multiple HTML elements across multiple files

I am toggling an arrow image whenever my div is clicked. I am controlling the state of the click with
const [toggleArrow, setToggleArrow] = useState(false)
My div has an onClick function that controls the state and toggles the faq-subject-toggle-arrow class that adds an image
<div className={`faq-subject ${toggleArrow ? 'faq-subject-toggle-arrow' : ''}`} onClick={() => {
setToggleArrow(!toggleArrow)
}>
My problem is that I have 50 divs across multiple styles and don't want to make 50 states to toggle one image.
Is there a more efficient solution for this with less code?
I created something that does the same thing. I extracted your code and made a component. now the state lives inside the component and will not affect others.
live demo
component
import { useState } from "react";
export const Button = () => {
const [toggleArrow, setToggleArrow] = useState(false);
return (
<div
style={{ width: "50px", height: "50px", margin: "10px" }}
className={`faq-subject ${toggleArrow ? "faq-subject-toggle-arrow" : ""}`}
onClick={() => {
setToggleArrow(!toggleArrow);
}}
></div>
);
};
css file, I didn't have the same classes so I created mine.
.faq-subject {
background: blue;
}
.faq-subject-toggle-arrow {
background: orange;
}
now you can use it wherever you want for multiple times
import { Button } from "./button";
import "./styles.css";
export default function App() {
return (
<div className="App">
<Button />
<Button />
<Button />
<Button />
<Button />
</div>
);
}

React hooks - set state of Parent from child via function

guys I am just learning React and I decide to do try to build Hero Database and I encounter a problem.
When I click on any of Heroes, Bio state and Display state updates with data about the hero and modal window pop up with more information about him. But I don't know how to close it. I have Modal as a separate component and when I am trying calling the function (updateDisplay) from child component. which should set State of Display to False it just doesn't work :/
Heroes.js
import React, { useState } from "react";
import Hero from "./Hero";
import styled from "styled-components";
function Heroes(props) {
const [Bio, setBio] = useState([]);
const [Display, setDisplay] = useState(false);
const SingleHeroCont = styled.div`
display: flex;
flex-direction: column;
margin-top: 10px;
padding: 10px;
align-items: center;
`;
const content = props.data.map((Hero) => (
<SingleHeroCont
onClick={() => {
setBio(Hero);
setDisplay(true);
}}
key={Hero.id}
>
<h1>{Hero.name}</h1>
<img src={Hero.images.sm} alt="Sorry guys"></img>
</SingleHeroCont>
));
const updateDisplay = () => {
setDisplay(false);
};
return (
<div className="heroes_cont">
<Hero updateDisplay={updateDisplay} Display={Display} BioData={Bio} />
{content}
</div>
);
}
export default Heroes;
Hero.js
import React from "react";
import styled from "styled-components";
function Hero({ Display, updateDisplay, BioData }) {
const HeroAbsolute = styled.div`
display: ${(props) => (props.showBio ? "block" : "none")};
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 255, 255, 0.5);
`;
return (
<HeroAbsolute showBio={Display}>
<div className="hero_bio_cont">
<h1>{BioData.name}</h1>
<button onClick={() => updateDisplay}>Close</button>
<div className="hero_bio_appearance">
<div>
<img></img>
<div>
<h2>{BioData.powerstats?.power}</h2>
<h2></h2>
<h2></h2>
</div>
</div>
</div>
</div>
</HeroAbsolute>
);
}
export default Hero;
<button onClick={() => updateDisplay}>Close</button>
As I see, the above code is not working to call updateDisplay function.
Correct usage would be
<button onClick={() => updateDisplay()}>Close</button>
Or
<button onClick={updateDisplay}>Close</button>
Please refer to the arrow function tutorial for the second case.

ReactJS onclick add or remove class to another element

I am struggling to convert my normal jQuery code in to React JS (I'm new to React).
I have the following code:
$(".add").click(function () {
$("nav").addClass("show");
});
$(".remove").click(function () {
$("nav").removeClass("show");
});
$(".toggle").click(function () {
$("nav").toggleClass("show");
});
nav {
width: 250px;
height: 150px;
background: #eee;
padding: 15px;
margin-top: 15px;
}
nav.show {
background: red;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<button class="add">Add</button>
<button class="remove">Remove</button>
<button class="toggle">Toggle</button>
<nav>Navigation menu</nav>
Tried references seems that only add/remove class for the same element:
https://stackoverflow.com/a/42630743/6191987
How to add or remove a className on event in ReactJS?
So, how can I convert or create the same jQuery methods to ReactJS?
Use the state that keeps the track of whether to show the nav or not.
Use a class name in the react code that corresponds to the state.
React uses "className" instead of "class" since "class" is already a reserved word in javascript.
You could check this sandbox link for implementation
function App() {
const [show, setShow] = React.useState();
return (
<div className="App">
<button className="add" onClick={() => setShow(true)}>
Add
</button>
<button className="remove" onClick={() => setShow(false)}>
Remove
</button>
<button className="toggle" onClick={() => setShow(!show)}>
Toggle
</button>
<nav className={show ? "show" : ""}>Navigation menu</nav>
</div>
);
}
You could combine the use useRef for nav and manipulate the ref (accessing nav's DOM) with event handlers for each button
import React from "react";
import "./styles.css";
export default function App() {
const navRef = React.useRef(null);
const onAddClick = (e) => {
navRef.current.classList.add("show");
};
const onRemoveClick = (e) => {
navRef.current.classList.remove("show");
};
const onToggleClick = (e) => {
navRef.current.classList.toggle("show");
};
return (
<div className="App">
<button onClick={onAddClick}>Add</button>
<button onClick={onRemoveClick}>Remove</button>
<button onClick={onToggleClick}>Toggle</button>
<nav ref={navRef}>Navigation menu</nav>
</div>
);
}
.App {
font-family: sans-serif;
}
nav {
width: 250px;
height: 150px;
background: #eee;
padding: 15px;
margin-top: 15px;
}
nav.show {
background: red;
color: white;
}
Codesanbox link for demo
Reference:
Refs and the DOM
useRef doc
Element.classList doc

Categories

Resources