I'm coding an application where people can make posts, and comment on them.
All of the posts are displayed on one page.
If a post is clicked the user gets routed to that post's page, which contains the full post, more details, and all of that post's comments.
Currently, I have the post div wrapped in a react-router Link. That works swell, except that when I click a button inside that div, I still get routed.
I want everywhere in the div to be "clickable", except actions like other Links or buttons.
<Link to={`/${_id}`}>
<div>
<button>I don't want this button to route</button>
</div>
</Link>
I'm not sure if there is a way to do this, but I can't find anything on it. I found one guy on another forum asking the same thing, but it was old and never got answered. Maybe I'm missing it, but I can't find it in the react-router docs. Maybe react-router is not even capable of this, idk?
Something like a quickfix but I don't know if its the best way to address this. I am looking first at the useRef but no avail.
Using something like e.preventDefault on the onClicks will probably save a lot of headache
<Link to="/">
<h1>Home</h1>
<button onClick={(e) => e.preventDefault()}>HAIYAAA</button>
</Link>
On hindsight this seems to be a Event Bubbling Issue right there.
See a fiddle here: https://codesandbox.io/s/react-router-forked-5rj2b?file=/index.js
EDIT:
Probably a much more dynamic way is to add a condition at the Link's OnClick and exclude the nested A (don't nest it otherwise React will nag you about it) and Button.
Basically we are dealing with a event bubbling here so might just use it to fine grain the behavior that we want. clicking anywhere inside the div will result to being routed to a page, while clicking any A or Button will not
<Link
to="/"
onClick={(e) => {
if (e.target !== e.currentTarget) {
if (["A", "BUTTON"].includes(e.target.nodeName)) {
e.preventDefault();
}
}
}}
>
<div>
Home
<br />
<button}>
HAIYAAA Don't Route me
</button>
<br />
<a href="#">
This is a link that is nested (Its not good to nest a!)
</a>
</div>
</Link>
Fiddle here: https://codesandbox.io/s/react-router-forked-4m4ww?file=/index.js
PS : ahh I spent time to learn something. Thanks for making my afternoon not a sleepy one
We need to stop the propagation of onClick event of the child to its parent.
<Link to="/">
<h1>Home</h1>
<button onClick={(e) => {
myNeededBehaviour();
e.stopPropagation();
}}>
HAIYAAA
</button>
</Link>
so, the stopPropagation will stop the event from propagating to its parent, and it will still calls myNeededBehaviour(); if you want, but the parent wont get the child's event. so it wont route, as it is not getting triggered.
Related
I am looking for someone to help me with the following issue:
I am trying to implement a modal system where the modals are dependent on the route using NextJS.
So say I am on the following page:
website.com/help
and say I have the modals category1, category2, and category3, all of which I would prefer to be able to persist after closing them (they are loading iframes), however this is not a must.
Then I would want the routes for these modals to be:
website.com/help/category1
website.com/help/category2
website.com/help/category3
I have already found this in the official NextJS examples:
with-route-as-modal
But the problem I am having is that with queryString routing, when you reload/visit the modal route directly, the modal wont be used. So the content will become full screen (it is a page of its own).
With dynamic routing, this is not an issue, since if you visit the modal route directly the modal will be kept. But the problem I am having with this is that these modals aren't exactly modals, the original page "behind" the modal just becomes the body background. The other issue is that I wont be able to persist these.
Here is the demo on stackblitz:
https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-route-as-modal?file=README.md
I would appreciate anyone helping me with this so much because it has really driven me mad trying to solve this!
I have a solution that you may like. For the example you provided you only need to import <Grid/> in /article/[articleId].js like it's done in /index.js
so when you open the modal the articles/posts list is shown in the background
// article/[articleId].js
import Grid from '../../components/Grid';
<>
<Modal
isOpen={true}
onRequestClose={() => router.push('/', undefined, { scroll: false })}
contentLabel="Post modal"
>
<Article id={articleId} pathname={router.pathname} />
</Modal>
<Grid />
</>
don't forget to give scroll false in router.push() and <Link/> so when you go back to articles/posts list it doesn't jump to the top of the page
router.push('/', undefined, { scroll: false })
<Link
key={index}
href="/article/[articleId]"
as={`/article/${id}`}
scroll={false}
>
<a className={styles.postCard}>{id}</a>
</Link>
you can see an example here: https://stackblitz.com/edit/github-rkrovd
I am somewhat new to frontend development and have just landed my first job in this area. I am working on a site right now built with React and Redux. The issue I am having is on a page which contains of several sections of divs. The buttons in the Navbar uses a React onClick-event to get the id of the section related to the button, and then "Scroll into view" to scroll down to the section. This works fine, though I want to be able to reach the same page and scroll into view from a different page. Here is an example from a Navbar button:
<li>
<FormattedMessage id="section.categories.funny">
{text => (
<button
type="button"
onClick={e => {
e.preventDefault();
if (document.getElementById('funny') !== null) {
document
.getElementById('funny')
.scrollIntoView({ block: 'start', behavior: 'smooth' });
}
}}
>
{text}
</button>
)}
</FormattedMessage>
</li>
So an example of this would be:
Let's say this page is on: 'url.com/categories'. When I press the button that says "funny" while on this url, the page scroll down to the section with the id of "funny" no problem. But I would also be able to be on an other page - let's say: "url.com/categories/stories" - have the same navbar there, and when I press the button that says "funny" I would like to be redirected to "url.com/categories" and then scrolled down to the "funny"-section.
I hope my question makes sense, and if it doesn't, let me know! English is not my native tongue and the fine art of asking the right questions seems to play a big role in learning how to code. :) As I said I am pretty new to this and haven't work a lot with React or Redux at all. Thank you! /Joel
I had the same issue and I used React-Router-Hash-Link
import { HashLink as Link } from 'react-router-hash-link';
<Link smooth to="/some/path#with-hash-fragment">Link to Hash Fragment</Link>
The smooth prop allows the element to be scrolled into.
So, I've been looking for a way to render this img tag on my dom without refresh the screen. But I didn't find a definitive answer on how to do that! I mean, in a natural way, with react library and without change a lot of things.
So, when I click this div, it calls a method
<div ref={(ref) => this.refProjectImageCenter = ref} onClick={(e) => this.selectImage(e, this.refProjectImageCenter)} >
<img src="images/projects/new-account.png" alt="new account" />
</div>
And in this method, I update my state with a new img element (not sure if it's the best way to do it tho)
selectImage(e: any , el: HTMLDivElement)
{
e.preventDefault(); // This is not working
this.setState({ selected_img: <img src={el.children[0].getAttribute("src")} /> });
}
And the state will update this part of the DOM
<div className="image detail">
{this.state.selected_img}
</div>
It renders the img indeed, but the page flashes(refresh), and I want to do that asynchronously. It's possible to do that with react? If it's not, how everybody is doing it right now? Thanks a lot.
I found the problem Henry and Shubham. I was updating the css class of the main html tag:
this.refMasterDOM.classList.remove("active");
Inside the method componentWillUpdate(). I removed this line and it stopped refreshing the page with sestate command. Although I don't know why.
I have a sliding-menu component.
It has items and I want to hide the menu when I click on each item. But if i click on
Now I did so:
<nav onClick={this.handleClickCloseMenu}>
<Link
to="/smth"
activeClassName="is-active"
>
smth
</Link>
<Link
to="/smth2"
activeClassName="is-active"
>
smth2
</Link>
</nav>
Now I have an eslint errors: jsx-a11y/no-noninteractive-element-interactions end jsx-a11y/no-static-element-interactions
I can set role button to nav but i guess it is wrong way. What do you think about?
I thought a little and decided to tie into the key parameter, it's generated by react-router. In componentDidUpdate, look at the key and if the current one differs from the previous one, then hide the menu. If it is open of course. streletss thank you for pushing a thought
Customary "I am new to React, Redux, and ES6"...
I need to notify my Component, or more specifically call a Action (or similar, I need to update an object in the store) whenever a user clicks on a redux-router Link. For example:
render(){
return (
<Link to={'/leaf/' + node.Id}>
<div className="col-md-2" style={divStyle}>
<label>
{node.Title}
</label>
</div>
</Link>
);
}
I want to be notified when the user clicks the Link. I don't want to stop anything from happening, I just want to fire off an async call back to the store so a variable gets updated.
How would I do this?
You can probably attach an onClick={// some function} prop to the Link element. If that doesn't work, you can add it to the label html element.
It shouldn't stop anything from propagating unless you specifically tell it to.