Make child element of Link not route - reactjs

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

Dynamic Modal routing with NextJS like Instagram

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

How can I use scroll into view from different/other page with react and redux?

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.

Update dom without refresh the page in react 16

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.

Click through nav handler eslint errors

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

Capturing onClick in a React Router Link

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.

Resources