React Router v4 - valid way to style Link component - reactjs

What is the most proper way to style <Link> component in React Router v4? If <Link> is simply an anchor tag, it shouldn't have <button> element nested inside. It also shouldn't be nested inside a button (because it doesn't make any sense), so the most valid way is to style it as a button. What are the cons of this approach?

Since the accessibility tag was added, I'll answer from that perspective.
First decide if you want a link or a button. A link is for navigational purposes. It takes you to another page or somewhere else on the current page. A button is for performing an action.
So you need to decide what should happen when the user selects the element. Are you navigating (link) or performing an action (button)?
If you use a link and style it as a button because you want an action to happen, such as "add to cart" or "register" or "login", then there are several accessibility issues to handle:
the role of the link needs to be set to button
you need to add a keyboard handler to allow the space key to activate the link. enter will already work but space is not a native action to a link. When the role is set to "button", a screen reader will announce the element as a button and will tell the user to "press spacebar to activate", so you need to handle that key.
However, this could be resolved much easier if you just use a <button> instead of an <a>. See the first rule of ARIA.

Related

React - setting focus on body element / understanding refs

So I'm trying to understand how to move focus when a new page loads in my application. This question came to my mind: what could I do if I want to focus on some element that is somewhere outside of my component. It seems to me that everywhere they write about the focus it's always used with refs. You can pass ref to a child. What if I want to focus on element to reset the focus on the page when a link is clicked and new page component is loaded? Or if I want to make skip link component higher in the tree and focus on a header in element? I have a lot of components, it doesn't seem a great idea to pass refs down through several components.
I feel like I'm missing something.
I'm interested about this because I'm learning about accessibility and how to make possible to navigate page only with keyboard.
what could I do if I want to focus on some element that is somewhere
outside of my component.
What if I want to focus on element to reset the focus on the page when
a link is clicked and new page component is loaded?
You can just pass callback of focus handler into your inner component and call it when you want.

How do I make an accessible onClick handler for links in React?

I have a link in my React application that calls an onClick handler as follows:
<a onClick={handleClick}>Link</a>
However, since I'm not using the native href attribute, this handler does not get activated when I focus the link, then press Enter.
Now, of course I could add an onKeyDown handler, then check whether the key that was pressed is Space or Enter and, if it is, call handleClick. However, I'm afraid that that won't be enough to capture all accessibility nuances, nor whether it will behave exactly like regular links.
Thus, the question is: is there a way to indicate that I want my function to be called when the link is followed by whatever possible interaction method?
an <a> tag without an href is no longer valid. Instead of trying to reimplement focus and keyboard logic, use a button and style however you like. Semantically, if it is firing an onClick it should most likely be a button and will be most accessible.
For reference https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md
You have the right idea onKeyDown or something needs to be set.
Ideally I would recommend using a library like Microsoft's FabricUI or Material which do all of this behind the scenes.
Alternatively you can use react-a11y package which has checks for such things. Following is the check for onClick
https://github.com/reactjs/react-a11y/blob/master/docs/rules/click-events-have-key-events.md

Using React Router to invoke state/functions?

I have a material-ui drawer, when the user clicks a button to open the drawer I'd like the url to change without a navigation actually happening, if someone visits the url (such as url.com/drawer) they'll land on the page with the drawer already open (or at least in the process of opening).
I would probably put ?drawer=open as a query string parameter rather than have it be a dedicated route. When the button is clicked, navigate to the current route with ?drawer=open appended, either by having the button actually being a styled Link, or using history.push.

How to refer to conditional elements when unit testing React components using jest and enzyme

I'm trying to test a component which should show a login and subscribe button when a user is not authenticated, but should show a logout button when a user is authenticated.
How should I refer to these buttons when making the test?
All examples I found is people doing things like:
expect(wrapper.find(Button).lenght).toBe(1); // or whatever
But this obviously doesn't fit my case, since I always have at least one button and they are all the same, except for its text and action.
So I think I need some way to refer to these buttons, so I could pass an authenticated prop and check if exactly the logout button is rendered.
What would be the best approach on doing that?
The options for selecting elements can be seen in the documentation for Selector.
In this case, you'd probably want to add css classes and use the class syntax, or perhaps the attribute syntax if your buttons use input elements where the text is set as an attribute.
You need to determine what differentiates each button. First, find the button:
const button = wrapper.find(Button)
Then expect() on some characteristic of the button. For example,
expect(button.props().children).toEqual('Subscribe')
or
expect(button.props().children).toEqual('Logout')
Just use filter:
wrraper.find(Button).filter({className:'any'})
wrraper.find(Button).filter({label:'any'})
...etc

Highlight a single button instance in a complex React page

My page is composed of hierarchy of classes and many reusable components. Multiple instances of a button component can exist anywhere in the page and on click they fire actions that populate different types of data in a common sidebar list component.
The requirement is to highlight the button that was last clicked to load the data in that sidebar list. Of course, it also means to remove highlighting from the previous button. Since these button can exist in different components, I cannot manage state in one parent component.
I am not able to find a solution in pure React. I don't want to use jQuery rather just stick to React. Note I do use Redux in the app though and would be fine with leveraging Redux state if required.
You should most definitely use Redux. You'll need to create a variable in Redux that gets updated whenever an action takes place that would require you to highlight the button on the page. Then use conditional styling for the button based on that variable.

Resources