Transition on conditional rendering in react JS - javascript

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.

Related

How Do I Traverse The DOM with Cypress Conditionally?

I would like to click the "View profile" button when the firstName of the user is equal to "Luke". There will be many users on one page.
HTML:
<div>
<div>
<a datcy="viewProfileButton">View profile</a>
</div>
<div>
<div>
<div>
<h5 datacy="firstName">Luke</h5>
</div>
</div>
</div>
</div>
Cypress Test:
cy.get('[datacy="firstName"]').contains($firstName)...
I've got to this point, but I am struggling with .parents() and other Cypress traversing options to move up the div, and then back down.
The .parent() and .children() function are pretty static and can be prone to cause flakiness if the structure of the HTML changes.
I would suggest setting up your HTML to allow for downward traversal from a higher level element.
In your case, if you have a common datacy attribute on the upper most <div> you can use cy.contains() and find() to do all the heavy lifting for you.
<!-- Added a second profile for example -->
<div datacy="profile">
<div>
<a datacy="viewProfileButton">View Luke's profile</a>
</div>
<div>
<div>
<div>
<h5 datacy="firstName">Luke</h5>
</div>
</div>
</div>
</div>
<div datacy="profile">
<div>
<a datacy="viewProfileButton">View Alice's profile</a>
</div>
<div>
<div>
<div>
<h5 datacy="firstName">Alice</h5>
</div>
</div>
</div>
</div>
// cy.contains returns the <div datacy='profile'> containing a child with the text 'Luke'
it('get link', () => {
cy.contains('[datacy="profile"]', 'Luke')
.find('a')
.should('have.text', "View Luke's profile");
cy.contains('[datacy="profile"]', 'Alice')
.find('a')
.should('have.text', "View Alice's profile");
});
Using cy.contains() to get parent element when child element contains text

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

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!

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.

React/js onClick on both the Parent div and Child div. Parent always fires

Hello i got a problem with having onClick on my parent and on its child that triggers which menuSection shows up. And even if i click on the child its the parents section that shows up. How to only trigger the child if that element gets clicked?
<div> onClick={() => props.onClick(MenuSection.Default)} >
<div <span><InfoIcon /></span> Some info</div>
<div>More Info</div>
<div>Even more Info</div>
<div onClick={() => props.onClick(MenuSection.NotDefault)}><InfoIcon /></div>
</div>
So here is how it looks and its always MenuSection.Default that shows up never MenuSection.NotDefault.
pass in e in the function and use
e.stopPropagation();
<div onClick={() => props.onClick(MenuSection.Default)} >
<div <span><InfoIcon /></span> Some info</div>
<div>More Info</div>
<div>Even more Info</div>
<div onClick={(e) => e.stopPropagation();props.onClick(MenuSection.NotDefault)}><InfoIcon /></div>
</div>
But I would also move the onClick inline function out of the render method and reference it with "this.nameOfClickMethod", nameOfClickMethod is of course to be named at your choise.
You can use event.stopPropagation(). It prevents the event from propagating.
<div> onClick={() => { props.onClick(MenuSection.Default)} } >
<div <span><InfoIcon /></span> Some info</div>
<div>More Info</div>
<div>Even more Info</div>
<div onClick={(e) => { e.stopPropagation();props.onClick(MenuSection.NotDefault)}}><InfoIcon /></div>
</div>

Online Example (CSS of a Cube) inside React

I am trying to reproduce this cube inside of a webpage I am making using react (i am very new to react, so this question might be stupid)
https://codepen.io/jordizle/pen/haIdo/
So, I created a component, which contains the HTML structure for the cube.
class Cube extends Component {
render() {
return (
<div className="cube">
<div id="wrapper">
<div class="viewport">
<div class="cube">
<div class="side">
<div class="cube-image">1</div>
</div>
<div class="side">
<div class="cube-image">2</div>
</div>
<div class="side">
<div class="cube-image">3</div>
</div>
<div class="side">
<div class="cube-image">4</div>
</div>
<div class="side">
<div class="cube-image">5</div>
</div>
<div class="side">
<div class="cube-image active">6</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
Then, I simply added the CSS from the above website to a separate file, which I imported, like so:
import './ProductPage.css';
(see link above for css. The CSS is just copy pasted).
Finally, I created another component, which should render the cube, when it itself is rendered:
class NewProductPage extends Component {
constructor(props) {
super(props);
this.state = {
img: null,
};
this.onDrop = this.onDrop.bind(this);
}
onDrop(acceptedFiles){
this.setState({
img: acceptedFiles[0].preview,
})
}
render(){
return (
<div>
<Cube />
<div className="DropPicBox">
<DropZone onDrop={this.onDrop}>
{this.state.img ?
<div>
<img className="PicBox" src={this.state.img} />
</div>
: null}
</DropZone>
</div>
</div>
);
}
}
This is rendered, but incorrectly:
My question is: is there something about the way react applies CSS that would change the way the cube looks? I used jfiddle to model this same cube using HTML and CSS from this website: https://codepen.io/jordizle/pen/haIdo/
And the cube looked correctly:
https://jsfiddle.net/jfj3muug/#&togetherjs=q2dv8HIMza
In JSX, to specify the class of an element, you have to use className, not class. E.g.:
<div className="foo">...</div>
instead of
<div class="foo">...</div>
You're doing that in some places, but Cube (your first codeblock) has class in several places.

Categories