react-router icon indicating copy to clipboard operation
react-router copied to clipboard

Can't use custom Component in Links

Open arnaudriegert opened this issue 4 years ago • 10 comments

Version

[email protected]

Test Case

https://codesandbox.io/s/react-router-forked-9c8pi?file=/index.js

The "fancy link" component's code comes directly from the docs.

Steps to reproduce

Click on the "💅 About" link.

Expected Behavior

Smooth transition to About page via the history API.

Actual Behavior

The page is reloaded completely.

Related

The workaround suggested in #6962 doesn't seem to work (and it shouldn't be necessary in the first place, or be documented). And I don't quite understand the reason for closing that issue.

arnaudriegert avatar Dec 24 '20 09:12 arnaudriegert

Yeah, the docs are off. You will need to do something like they do in the default component prop to create your own onClick method. https://github.com/ReactTraining/react-router/blob/ebd1528bafebd81ca9b813f722c8f1368bb57e7e/packages/react-router-dom/modules/Link.js#L35-L52

pshrmn avatar Dec 25 '20 20:12 pshrmn

Hello, I came across this issue with the same problem today. Using the direction that @pshrmn gave, I added the following to my component. Hope this helps?

const isModifiedEvent = event => (!!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey))

const handleClick = (event, navigate, target, onClick) => {
    try {
        if (onClick) onClick(event);
    } catch (ex) {
        event.preventDefault();
        throw ex;
    }
    
    if (
        !event.defaultPrevented && // onClick prevented default
        event.button === 0 && // ignore everything but left clicks
        (!target || target === "_self") && // let browser handle "target=_blank" etc.
        !isModifiedEvent(event) // ignore clicks with modifier keys
    )
    {
        event.preventDefault();
        navigate();
    }
}

Then on your <a> element, add:

onClick={event => {handleClick(event, navigate, target, onClick)}}

navigate and target have come from props, something like:

const { children, className, navigate, target, onClick, ...rest }  = props;

martingarnett01 avatar Jan 07 '21 19:01 martingarnett01

Any update on this?

The workaround seems to be complicated. Also, is this a bug to be fixed?

tuanalumi avatar May 10 '21 11:05 tuanalumi

I just switched the Link to an <a /> tag with href. I still reload the target page and reload my bundle (which I shall now code-split with this new route as well), but hey stuff doesn't break. Will update once I have time to follow up with @pshrmn's solution

morsmodr avatar Jun 24 '21 04:06 morsmodr

Having not been around when this was designed in v5, I can't speak to why, but the component prop expects a component that takes a navigate prop instead of simply onClick. I don't think we can really change it at this point, as it would be a breaking change, but I do think we should at least update the docs to be clear on the workaround in v5.

Note if you are planning to update to v6, please see https://github.com/remix-run/react-router/pull/7998 which includes a full example of a custom Link that uses new APIs that should be a lot clearer than the component prop.

chaance avatar Sep 04 '21 06:09 chaance

I know this is not ideal, and we'll figure out a better workaround, but I spun up a quick example of a custom Link implementation that should work in the mean time. https://codesandbox.io/s/custom-link-example-rrv5-zk2vm?file=/src/App.js

chaance avatar Sep 04 '21 17:09 chaance

as suggested in #7844 (marked as duplicate). Can you expose LinkAnchor, so we can use wrap it with custom logic? I had to duplicate it in my code :/

It used to be here - https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/Link.js, I can't find it anymore.

KutnerUri avatar Oct 31 '21 17:10 KutnerUri

oh - I see LinkAnchor is replaced in V6 with the useLinkClickHandler() hook, which breaks compatibility with react 15 but is otherwise awesome.

https://reactrouter.com/docs/en/v6/upgrading/v5#remove-link-component-prop

KutnerUri avatar Nov 10 '21 11:11 KutnerUri

I just realized this doesn't work for NavLink. I looked at the source code, and it's doing a lot of other stuff. :( Please advise!

KutnerUri avatar Dec 20 '21 15:12 KutnerUri

If it doesn't work it could be removed from the docs, we lost quite a bit of time trying back and forth before finding this issue.

tomsotte avatar Feb 25 '22 17:02 tomsotte

This issue has been automatically marked stale because we haven't received a response from the original author in a while 🙈. This automation helps keep the issue tracker clean from issues that are not actionable. Please reach out if you have more information for us or you think this issue shouldn't be closed! 🙂 If you don't do so within 7 days, this issue will be automatically closed.

github-actions[bot] avatar Apr 26 '23 20:04 github-actions[bot]

This issue has been automatically closed because we haven't received a response from the original author 🙈. This automation helps keep the issue tracker clean from issues that aren't actionable. Please reach out if you have more information for us! 🙂

github-actions[bot] avatar May 06 '23 21:05 github-actions[bot]