Screen reader not reading the Headings when navigating back - React JS - reactjs

I want to make the headings (H1 tag) to be auto focused on page load so the screen reader can read the headings.
With the below code I made it work as expected.
<fieldset> <h1 role="alert"> <a id="specialfocusable" tabIndex={-1}> Component A </a> </h1> </fieldset>
My app is like a stepper, were we move from component A to Component B similarly Component B to component A.
Problem is when navigating from Component B to component A heading text is not read by screen reader.
Please help me to resolve this problem as I'm not finding any solution.
Below is the app link,
https://stackblitz.com/edit/react-ts-ckrut8?file=a.tsx

Simply cleaning up that code should be enough:
<h1 id="h1" tabindex="-1">Component 1</h1>
followed by
h1.focus()
There is a lot wrong in the posted code, which might cause the issues with the screen reader.
Most importantly it’s changing the H1’s role. Most screen reader users rely on finding headlines for orientation and navigation. There are shortcuts that help jump directly to the H1, for example.
An alert is not needed since focus is being moved to the headline. It will get announced on focus.
A <fieldset> is for forms and would need to have an accessible name. It’s simply invalid here.
How to React that?
To focus an element you’ll need to access the rendered DOM. Therefore you use the ref property along with useRef()
function MyComponent() {
const h1Ref = useRef(null);
useEffect(() => {
h1Ref.current.focus();
}, []);
return <h1 ref={h1Ref} tabIndex={-1} />;
}

Related

How to save toggled tag to local storage in React JS?

In my previous question, after I got the toggle working, I asked if there was a way I could keep it there, to which the person who answered my question told me to use local storage.
As far as the refresh problem goes, React doesn't persist data across
refreshes. You could use sessionStorage to do this for example, but I
think that would fit better as a separate question if you don't figure
it out.
...Or use localStorage if you don't want the data to be cleared when
the page session ends.
Then I started researching about local storage and how to use it in React JS. I tried coding it myself, but it ended up being very complicated and my code was so messy.
The thing is, that question also had to do with my money tracker app. Basically, the text being toggled was instead a tag being toggled.
Here are some parts of the money tracker app's documentation that I wrote in my docs on novem. website:
The first bar with the cyan plus sign is called the input bar. You add in something like $8.00 - Bought a shirt, and a output bar (the
bar with the 3 buttons on the right) is what you get with what you
entered in.
A bit later...
The first one, the one with the cyan background, is the spent button. To put it simple, it toggles a tag with a cyan background that
says spent.
The second one, the button in the middle, is the earned button. It does the same thing as the spent button but instead of the words spent
it says earned.
The last one is the delete button that deletes the whole output bar.
Note: It might be better if you see the website, because it is a very short page.
React JS snippet of my code
<div className="bar-tag-container">
<li className={`todo-item ${todo.completed ? "completed" : ""}`}>
{isSpent && <p className="tag">Spent</p>}
{isReceived && <p className="tag">Earned</p>}
<div className="others">{text}</div>
</li>
</div>
<button
onClick={(() => setIsSpent(!isSpent), handleClickSpent)}
className="spent-btn"
>
<FaMoneyCheckAlt />
</button>
<button
onClick={(() => setIsReceived(!isReceived), handleClickReceived)}
className="receive-btn"
>
<FaDollarSign />
</button>
Based on the code from you previous question.
To set onClick the value of your input you can do it in a function handleClick like so :
import React, { useState } from "react";
const handleClick = () => {
setShowText(!showText)
localStorage.setItem('myText', showText);
}
const Test = () => {
const [showText, setShowText] = useState(false);
return (
<React.Fragment>
{showText && <h1>Hello World</h1>}
<button onClick={() => handleClick}>Toggle</button>
</React.Fragment>
);
};

ReactDOM.render does not re-render the 2nd element on the list

im having problem with ReactJS, i
on index.js i have:
ReactDOM.render([<App />, <Footer />], document.getElementById('root'));
the problem is that Footer needs to add an 80px padding from the bottom only on certain pages
so on the render method i do
<div>
{isMobile && window.location.pathname.startsWith('/summary') &&
<div style={{height: 80}}></div> }
</div>
but it doesn't re-render when window.location.pathname changes,
i move around the web app and it doesn't change only when i hit F5 it renders correctly on that page.
i tried using events on window but they're aren't invoked as well...
window.addEventListener('locationchange', function(){
console.log('xxxxxxx location changed!');
})
window.addEventListener('hashchange', function(e){console.log('xxxxxx hash changed')});
window.addEventListener('popstate', function(e){console.log('xxxxxxx url changed')});
how i can make it re-render? or make Footer work as React component that can render ?
This is a common problem!
Out of the box, React is configured to operate on a single page (see Single Page Applications), which basically means it deletes what's shown on screen and renders new information when an update is required.
Naturally, simulating the routing behavior that's observable for non Single Page Apps is a little more difficult - check out React Router, which is a library created to tackle this exact issue.

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.

How to create popup with YouTube video that not affect main page?

I'm trying to have popup window with YouTube video that not affect the main page.
I can still interact with the main page, similar on this web site when you click track you have small popup video on right bottom corner.
I have App.js with YouTube API
{
getYouTubeApi = (searchTerms1, searchTerms2) => {
fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=10&q=${searchTerms1} ${searchTerms2}&type=video&key=YOUR_KEY`)
.then(res=>res.json())
.then(data=>{
this.setState({videoId: data.items[0].id.videoId})
})
.catch(error=>console.log(error))
}
render(){
return (<YouTube opts={opts} videoId={this.state.videoId} />)
}
}
getYouTubeApi function I call on click on track that just bring to the top of my page where YouTube video loads.
Here is my school project.
Since this describes DOM behavior more than business logic, you could put in whatever you want in a specific component that behaves like a modal (whether by swapping out css classes or setting inline styles based on certain conditions).
To make this modal reusable, I'll suggest you make it a higher order component to wrap around <Youtube /> component or any other component you want to display with modals.
For example, you could have
const Modal = (ComponentToDisplayAsModal, props) => (
<div class="modal">
<ComponentToDisplayAsModal {...props} />
</div>
)
You could then style the modal class to behave like a modal.
On the view you wish to show your modal, you could render
Modal(Youtube, props)

Resources