Why Mac VoiceOver doesn't detect after mounting ReactJs Component? - javascript

I have this code in App.js. Mac's voice over can detect all the elements on this page and it keeps spelling out the text on each one by one.
const WelcomePage = () => {
const [isWarningPage, setisWarningPage] = useState(false);
if (!isWarningPage) {
return (
<>
<div class="container-fluid">
<div className="welcome-section">
<div className="logo-container">
<img src={logo} alt="" />
</div>
<div className="welcome-content">
<h2 aria-level="1">Welcome to My Website</h2>
<h5 aria-level="5">
Connecting you to my web.
</h5>
<h5 className="child2" aria-level="5">
We are happy to see you.
</h5>
</div>
<div>
<button
onClick={() => setisWarningPage(true)}
id="GetStartedBtn"
aria-label="Get Started"
>
Get Started
</button>
</div>
</div>
</div>
</>
);
}
return PhishingWarningPage;
};
But, when I click on the "Get Started" button, Mac's Voice Over cannot detect the mounted component (Warning page). Then I focused the element using some javascript. Why does it happens?
What are my options here?
Thank you!

Related

gatsby load custom script specific page every visit

i have a blog website that i write using gatsby and i tried to load a isso custom script for specific page, which is my article page.
It load for once only and it didn't load after i visit the page again
im using Script element for it
here's my custom script component:
const Comment = ({post_id}) => {
return (
<>
<Script data-isso="//comments.example.ltd/"
src="//comments.example.ltd/js/embed.min.js"
id={post_id}
/>
</>
)
}
and here's the main layout for my article page
<Base>
<div className="post template">
<SEO title="{`${post.title}" | ${config.siteTitle}`} />
<div className="post page">
<div className="article figure">
<div className="HeaderContainer">
<small className="sub">
{post.date}
</small>
<h1 className="title">
{post.title}
</h1>
</div>
<MDXProvider>
{children}
</MDXProvider>
</div>
</div>
</div>
<Comment post_id={post.title}/>
</Base>

Uncaught TypeError: Cannot read properties of null (reading 'offsetTop')

I was trying to create a scroll effect. When you click on the options on the navbar, we go to a specific section.
Why am I getting this error?
This is the code where the error is coming:
import React, { useRef } from 'react'
export default function Home() {
const about = useRef(null);
const work = useRef(null);
const contact = useRef(null);
const scrollSection = (elementRef) => {
window.scrollTo({
top: elementRef.current.offsetTop,
behavior: "smooth",
});
};
return (
<>
<div ref={about} className='first'>
<nav className="navbar">
<div className="logo">
<video loop autoPlay muted playsInline className='logo_video' >
<source src={video} type="video/mp4" />
</video>
</div>
<div className="about_section">
<ul className="list">
<li className="info about">
<div className="infoindex" onClick={() => scrollSection(about)}>
About
</div>
</li>
<li className="info">
<div className="infoindex" onClick={scrollSection(work)}>
Work
</div>
</li>
<li className="info">
<div className="infoindex" onClick={scrollSection(contact)}>
Contact
</div>
</li>
</ul>
</div>
</nav>
What are some edits I can do to this code?
Take a look to the following lines of code:
<div className="infoindex" onClick={() => scrollSection(about)}>
<div className="infoindex" onClick={scrollSection(work)}>
<div className="infoindex" onClick={scrollSection(contact)}>
Now you can see the difference. scrollSection(work) and scrollSection(contact) are triggering the scrollSection function in each render even if you don't click them. Don't forget to add the arrow function to them.
<div className="infoindex" onClick={() => scrollSection(about)}>
<div className="infoindex" onClick={() => scrollSection(work)}>
<div className="infoindex" onClick={() => scrollSection(contact)}>
By the way, you are only handling the about reference at the div parent:
<div ref={about} className='first'>
You need to handle the rest of references too and don't forget the onClick event. If your about div wraps the rest of the divs, then it could have unwanted behaviors if you want to click the child divs inside the parent div.
You are not passing work and contact refs to elements as you are doing with the about ref. They are never being set, and this is why you are getting null current.
You should not call the scrollSection directly in the onClick, but rather pass a callback function that executes when the div is clicked:
<div className="infoindex" onClick={() => scrollSection(work)>Work</div>
and
<div className="infoindex" onClick={() => scrollSection(contact)}>Contact</div>

how to replace h2 with div on same page after on click with h2 (and without using component)

I am very new to stack overflow and this is also my first post so I am not sure if this question is specific/detailed enough but...: I am trying to figure out how to replace the h2 element 'Unpack the Week' with the div between the comments. For now I am trying to avoid rendering a new component and simply just have a div hiding until the h2 element is clicked to view the information inside of that div (my project is all on one page/one path). I created a weekToggle function attached to the h2 but I dont think its the right direction of what I want.
enter code here
const weekToggle = () => {
console.log('clicked');
return (
<div>
<img src="" alt="" />
<h4>Monday</h4>
<img src="" alt="" />
<h4>75˚/65˚</h4>
</div>
)
}
return (
<div>
<div>
<img src={unpackedImg(cityConditions)} alt="" />
<div>
<img src={iconImg(cityConditions)} alt="" />
<h1>{cityName}</h1>
<h2>{cityTemp}</h2>
<div>
<div>
<h3>{cityConditions}</h3>
<p>Conditions</p>
</div>
<div>
<h3>{cityWind}mph</h3>
<p>Wind speed</p>
</div>
<div>
<h3>{cityHumidity}%</h3>
<p>Humidity</p>
</div>
</div>
</div>
</div>
<h1>{cityName} unpacked!</h1>
<div>
{/* after clicking h2 element 'Unpack the Week' replace h2 with this div */}
{/* ---------------------------------------------------------------------*/}
<h2 onClick={weekToggle}>Unpack the Week</h2>
<div>
<img src="" alt="" />
<h4>Monday</h4>
<img src="" alt="" />
<h4>75˚/65˚</h4>
</div>
{/* ---------------------------------------------------------------------*/}
</div>
</div>
)
}
Weather.propTypes = {
weather: PropTypes.object
}
I'm assuming you want to build collapsible element with details regarding temperatures for the whole week. The proper way to do it in React is using the hook useState which holds the information whether the details are visible or not. I re-designed your component a bit to show the idea.
import {useState} from "react";
function CityWeather ({cityName, cityTemp, cityConditions}) {
const [showDetails, setShowDetails] = useState(false);
return (
<div>
<h1>{cityName}</h1>
<h2>{cityTemp}
<span style={{cursor: 'pointer'}} onClick={() => setShowDetails(!showDetails)}>
{ showDetails ? <>▲</> : <>▼</> }
</span>
</h2>
{ showDetails &&
<div>
<div>
<h4>Monday</h4>
<h4>75˚/65˚</h4>
</div>
<div>
<h4>Tuesday</h4>
<h4>76˚/66˚</h4>
</div>
<div>
<h4>Wednesday</h4>
<h4>77˚/67˚</h4>
</div>
</div>
}
<div>
<div>
<h3>{cityConditions}</h3>
<p>Conditions</p>
</div>
</div>
</div>
)
}
use this component in your App like this:
<CityWeather cityName="London" cityTemp="75˚" cityConditions="fair"/>
Feel free to comment if you need any explanation.

Why are my array items getting added to the top, and the scroll is staying at the top?

I'm creating a chat app, and I want to load more messages on button click that sits at the top. It works perfectly, however when I click the load more button, the items get added at the top, and the scroll position remains at the top. However I want to load them, and the scroll position has to remain at the last top-most item. Right now my code is as follows:
Chat.js return method
return (
<div className="page">
<div className="page__title">Chat</div>
<article className="chat">
{!!conversations.length && (
<div className="chat__conversations">
<ul className="chat__left list">
{conversations.map((_conversation, index) => (
<li key={index} className="list__item">
<button className="list__link"
onClick={() => setCurrentConversation(_conversation)}>
{getRecipient(_conversation).name}
</button>
</li>
))}
</ul>
</div>
)}
{
conversation && !!messages.length && (
<div className="chat__right">
<Messages messages={messages} isOwnMessage={isOwnMessage} hasMore={hasMore}
getMessages={getMessages}/>
<form className="form" onSubmit={sendMessage}>
<input className="form__input message__input"
placeholder="Tryk Enter for at sende en besked"
value={message}
onChange={e => setMessage(e.target.value)}/>
</form>
</div>
)
}
</article>
</div>
)
Messages component
return (
<ScrollToBottom className="chat__messages">
<button className="btn"
disabled={!hasMore}
onClick={() => getMessages()}>{hasMore ? 'Hent flere beskeder' : 'Ikke flere beskeder'}</button>
{messages.map((_message, index) => (
<div key={index}>
{isOwnMessage(_message) ? (
<div className="message">
<div className="message__user">
<p className="message__user-name">{_message.user.name}</p>
<p className="message__user-date">{moment(_message.createdAt).fromNow()}</p>
</div>
<span className="message__text">{_message.text}</span>
</div>
) : (
<div className="message">
<span className="message__text">{_message.text}</span>
<div className="message__user">
<p className="message__user-name">{_message.user.name}</p>
<p className="message__user-date">{moment(_message.createdAt).fromNow()}</p>
</div>
</div>
)}
</div>
))}
</ScrollToBottom>
)
Sounds like you want to use the scrollTo method.
You need to use scrollTop and scrollLeft to get vertical and horizontal scroll position. You can store this info in state so that once additional data is loaded, you can use scrollTo for scrolling to older position.

Transition on conditional rendering in react JS

I have this conditional render function ready and it works fine.
render() {
if (this.state.guess === 'guessing') {
return (
<div style={rightBarStyle.guessingGameStyle}>
<div style={rightBarStyle.guessingGameStyle.quizBlockStyle}>
<h3> Who is this? </h3>
<ul className={'optionsContainer'}>
<PeopleNames onClick={(e) => this.handleClick(e)}/>
</ul>
</div>
<div style={rightBarStyle.guessingGameStyle.imgBlockStyle}>
<img style={rightBarStyle.guessingGameStyle.imgBlockStyle.image} src={imageLink}
alt={"profile pic"}/>
</div>
</div>
)
}
else if (this.state.guess === 'correct') {
return (
<div style={rightBarStyle.guessingGameStyle}>
<div style={rightBarStyle.guessingGameStyle.quizBlockStyle}>
<FadeIn>
<p className={['details','title'].join(' ')}>{name} </p>
<p className={['details','designation'].join(' ')}>Software Developer</p>
<p className={['details','team'].join(' ')}>Software Department</p>
</FadeIn>
</div>
<div style={rightBarStyle.guessingGameStyle.imgBlockStyle}>
<img style={rightBarStyle.guessingGameStyle.imgBlockStyle.image} src={imageLink}
alt={"profile pic"}/>
</div>
</div>
)
}
else return <div></div>
}
Issues:
I need to apply a transition whenever new DOM elements are rendered on state change. I read about CSSTransitions but they work on child elements.
Here is the sandbox link on which I want to have a smooth transition onclick of the button: SandBox
I have to include that last 'else' otherwise it throws an error that render didn't find anything to be rendered on DOM. It works but is there a workaround for this? It does not look neat.

Categories