scrollIntoView onClick reactjs - javascript

hello I have a few buttons and I want to scroll to them when clicked.
const [active, setActive] = useState(0);
useEffect(() => {
// I´m not using useRef. is there other way to automatically scroll to the element and stop at 0 0 of the page?
})
<div style={{height: '10000px'}} />
<button onClick={() setActive(1)}>button 1</button>
<button onClick={() setActive(2)}>button 2</button>
<button onClick={() setActive(3)}>button 3</button>
<div style={{height: '10000px'}} />
as you can see there´s a lot of scroll caused by those 2 divs. the idea is to scroll down and when you reach the buttons and click the one you need. the page scrolls to that button leaving it in the top of the page
image 1: scroll in random position
image 2: when you click on button 1
image 3: when you click on button 2
image 4: when you click on button 3

For scrolling react view to top there is a simple function.
use window.scrollTo(0, 0);
inside your code try this.
<button onClick={()=> window.scrollTo(0, 0) }>button 1</button>
edited:
I could come up with this solution after you edited your question.
import React, { useRef } from "react";
export default function App() {
const button1Ref = useRef();
const button2Ref = useRef();
const button3Ref = useRef();
const handleScroll = ref => {
window.scrollTo({
behavior: "smooth",
top: ref.current.offsetTop
});
};
return (
<div className="App">
<div style={{ height: "10000px" }} />
<div>
<button ref={button1Ref} onClick={() => handleScroll(button1Ref)}>
button 1
</button>
</div>
<div>
<button ref={button2Ref} onClick={() => handleScroll(button2Ref)}>
button 2
</button>
</div>
<div>
<button ref={button3Ref} onClick={() => handleScroll(button3Ref)}>
button 3
</button>
</div>
<div style={{ height: "10000px" }} />
</div>
);
}
Please try it out. Let me know if this is what you asked for.
Edited after question asked in comment for using single component with Ref and using that component in multiple numbers:
If you want to use a single component for button then try this,
import React, { useRef } from "react";
export default function App() {
return (
<div className="App">
<div style={{ height: "10000px" }} />
<MyButton>button 1</MyButton>
<MyButton>button 2</MyButton>
<MyButton>button 3</MyButton>
<div style={{ height: "10000px" }} />
</div>
);
}
const MyButton = props => {
const buttonRef = useRef();
const handleScroll = () => {
window.scrollTo({
behavior: "smooth",
top: buttonRef.current.offsetTop
});
};
return (
<div>
<button ref={buttonRef} onClick={handleScroll}>
{props.children}
</button>
</div>
);
};

Here you want to use an event handler.
const handleClick = (e) => {
// scrollIntoView logic and set state
}
<div onClick={handleClick}/>

//action
const goDown= (e) => {
const anchor = document.querySelector('#some-id')
anchor.scrollIntoView({ behavior: 'smooth', block: 'center' })
}
// click to scroll
<Link onClick={goDown}>Choose Health</Link>
//element you want to scroll to
<div id='some-id'>
</div>

Related

Show/Hide Component by passing useState Value React

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;

How to hide box on body click except of button in using ReactJS Hooks?

T have a button with a box & box will hide/show (toggle) on button click. This is working fine now I want to when we click on body except of button then box should be hide.
My Code:-
function App() {
const [show, setShow] = useState(false);
return (
<div>
<button className="btn" onClick={() => setShow(!show)}></button>
{show ? <div className="box"></div>
: null}
</div>
);
}
export default App;
ThankYou for your efforts!
There's many tricks to solve this. But one of them I prefer, do it like modals. So:
Add background div beside of the box that shows back of the box
Set onClick on this new div to hide the box
function App() {
const [show, setShow] = useState(false);
return (
<div>
<button className="btn" onClick={() => setShow(!show)}></button>
{show && (
<>
<div style={{bottom:0 , top:0, right:0, left:0,position:"absolute"}} onClick={()=> setShow(false)}></div>
<div className="box"></div>
</>)
}
</div>
);
export default App;
If I got your point rightly. You can solve it like this.
It will close the box/modal when one clicks outside of the modal or body
function App() {
const [show, setShow] = useState(false);
return (
<div>
<button className="btn" onClick={() => setShow(!show)}></button>
{show ?
<div onClick={() => setShow(false)}
style={{width: '100vw',
height: '100vh',
position: 'absolute',
top: 0,
left: 0
}}>
<div className="box" onClick={(e) => e.stopPropagation()}></div>
</div>
);
}
export default App;

React: Preview content while typing

I have a simple list where I'm adding media content.
I'm using Embed to display the media contents.
When I want to enter a media link suck as Youtube/twitter .., I want to be able to preview it after pasting it and before clicking on Add.
I tried to add an onChange but didn't work. How to do so ?
https://codesandbox.io/s/vigorous-greider-seycx?file=/src/App.js:0-1201
import React, { useState } from "react";
import Embed from "react-embed";
export default () => {
const reactList = [
{
id: "2",
title: "Twitter",
media: "https://twitter.com/Betclic/status/1382074820628783116?s=20"
}
];
const [links, setLinks] = useState(reactList);
const [media, setMedia] = React.useState("");
function handleChange(event) {
setMedia(event.target.value);
}
function handleAdd() {
const newList = links.concat({ media });
setLinks(newList);
}
return (
<div>
<div>
<input type="text" value={media} onChange={handleChange} />
<div
style={{ height: "250px", width: "500px", border: "3px solid black" }}
>
Preview
<Embed url={media} onChange={handleChange} />
</div>
<button type="button" onClick={handleAdd}>
Add
</button>
</div>
<ul>
<div style={{ width: "50vh" }}>
{links.reverse().map((url, indexurl) => (
<li key={url.id}>
<div>{url.title}</div>
<Embed url={url.media} />
</li>
))}
</div>
</ul>
</div>
);
};
I think I have to set an automatic refresh for the component, because when I set the link in a modal, after closing and reopening the modal, it works. What do you think?

HTML elements not rendering with button's onClick event in React JS

I am relatively new to React and want to render input forms on click of a button. The function called in button's onClick works for stuff like console.log() but does not render the HTML elements. I have absolutely no clue as to why is this happening. I am using function component.
Below is the code snippet that is concerned with the problem.
const UserAppointment = () => {
function renderHtml () {
return(
<div>
<h1>I want this to render on click</h1>
</div>
)
}
return (
<div>
<button onClick={renderHtml}>Render Input forms</button>
<br /><br /><br />
<button onClick={()=> { dispatch(logout()) }}>Logout</button>
</div>
)
}
export default UserAppointment ;
I suggest you should use state to save and render html:
const UserAppointment = () => {
const [html, setHtml] = useState(null);
function renderHtml () {
return(
<div>
<h1>I want this to render on click</h1>
</div>
)
}
return (
<div>
{html}
<button onClick={(() => setHtml(renderHtml()))}>Render Input forms</button>
<br /><br /><br />
<button onClick={() => { dispatch(logout()) }}>Logout</button>
</div>
)
}
Instead of a renderHtml function, have a boolean state. When clicked, toggle the boolean, and conditionally return the JSX when true:
const App = () => {
const [show, setShow] = React.useState(false);
return (
<div>
<button onClick={() => setShow(!show)}>Render Input forms</button>
<br /><br /><br />
<button onClick={()=> { dispatch(logout()) }}>Logout</button>
{
!show ? null : (
<div>
<h1>I want this to render on click</h1>
</div>
)
}
</div>
)
};
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div class="react"></div>
When you use event handlers such as onClick(), React doesn't return any HTML back from the function that you pass in.
Like other commenters said, you need to use React state to manage when your div is shown and when it is hidden.
First set the state since you are using functional component.
const [Heading, setHeading] = useState("")
Then use your onClick event and pass a function to it.
<button onClick={renderHtml}>Render Input forms</button>
Set your state to the heading inside renderHtml function.
const renderHtml =()=> {
setHeading("I want this to render on click")
}
Display your heading in h1 in return.
<h1>{Heading}</h1>
Full code:
const [Heading, setHeading] = useState("")
const renderHtml =()=> {
setHeading("I want this to render on click")
}
return (
<div>
<h1>{Heading}</h1>
<button onClick={renderHtml}>Render Input forms</button>
<br /><br /><br />
<button onClick={() => { dispatch(logout()) }}>Logout</button>
</div>
)
}

sending data through a datalist in react

So over the last few months i started from 0 and started learning react. While it is a challenge i was heavily encouraged to keep going. Ive been pointed in the right direction a multitude of times thanks to stack overflow and am asking for help again. Right now i have a react component that makes a model popup.
In that popup i want to have a selectable list that can be submitted and posted. The idea is exactly like a data list. Which i am trying to do in react, currently the only way i know to send something in react is using axois library but im not able to render anything in the modal model. So i decide to make a jsx datalist in the modal body itself.
Is this the right way to go about it? is there an easier way to accomplish what i want to do within the model?
const ModalExample = (props) => {
const {
className
} = props;
const [modal, setModal] = useState(false);
const toggle = () => setModal(!modal);
const externalCloseBtn = <button className="close" style={{ position: 'absolute', top: '15px', right: '15px' }} onClick={toggle}>×</button>;
return (
<div>
<Button color="danger" onClick={toggle}>OTHER</Button>
<Modal isOpen={modal} toggle={toggle} className={className} external={externalCloseBtn}>
<ModalHeader>Add any soft skills that you believe you have</ModalHeader>
<ModalBody>
<form action="/amazonaws.com/updateSkill">
<input list="other1" name="other2" />
<datalist id="other1">
</option><option value="excellent Communication ">
</option><option value="Leadership experience">
</option><option value="Ability to work under pressure">
</option><option value="High work ethic">
</option><option value="Organized">
</option></datalist>
<input type="submit" />
</form>
</ModalBody>
<ModalFooter>
{/* <Button color="primary" onClick={toggle}>Do Something</Button>{' '}*/}
<Button color="secondary" onClick={toggle}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
);
}
export default ModalExample;
Thank you in advance
As I understand you want to get a data list from API and show it in the HTML section so add your API response to the state and use it in return section to show data in proper HTML tags.
const ModalExample = (props) => {
const {
className
} = props;
const [modal, setModal] = useState(false);
const [response, setResponse] = useState(false);
const apiCall = () => {
axios
.get("http://")
.then((response) => {
setResponse(response);
}).catch((error) => {
console.err(error);
});
}
useEffect(() => {
apiCall();
}, [value]);
const toggle = () => setModal(!modal);
const externalCloseBtn = <button className="close" style={{ position: 'absolute', top: '15px', right: '15px' }} onClick={toggle}>×</button>;
return (
<div>
<Button color="danger" onClick={toggle}>OTHER</Button>
<Modal isOpen={modal} toggle={toggle} className={className} external={externalCloseBtn}>
<ModalHeader>Add any soft skills that you believe you have</ModalHeader>
<ModalBody>
<form action="/amazonaws.com/updateSkill">
<input list="other1" name="other2" />
<datalist id="other1">
{response}
</datalist>
<input type="submit" />
</form>
</ModalBody>
<ModalFooter>
{/* <Button color="primary" onClick={toggle}>Do Something</Button>{' '}*/}
<Button color="secondary" onClick={toggle}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
);
}
export default ModalExample;

Categories