import React, { useEffect, useState } from "react";
import styled from "styled-components";
import arcade from "../assets/images/icon-arcade.svg";
import advanced from "../assets/images/icon-advanced.svg";
import pro from "../assets/images/icon-pro.svg";
const SelectYourPlan = () => {
const [toggle, setToggle] = useState(0);
const [init, setInit] = useState(true);
useEffect(() => {
console.log(toggle);
console.log(init);
if (toggle === 0) {
document.getElementsByClassName("ball")[0].style.marginLeft = "0vw";
document.getElementById("left").style.color = "hsl(213, 96%, 18%)";
document.getElementById("right").style.color = "hsl(231, 11%, 63%)";
if (init === false) {
let arcade = document.getElementsByClassName("arcade")[0];
let advanced = document.getElementsByClassName("advanced")[0];
let pro = document.getElementsByClassName("pro")[0];
let arcadePrice = document.getElementById("arcadePrice");
let advancedPrice = document.getElementById("advancedPrice");
let proPrice = document.getElementById("proPrice");
arcadePrice.textContent = "$9/month";
advancedPrice.textContent = "$12/month";
proPrice.textContent = "$15/month";
arcade.removeChild(arcade.lastElementChild);
advanced.removeChild(advanced.lastElementChild);
pro.removeChild(pro.lastElementChild);
}
} else {
let extraContentElement = document.createElement("p");
extraContentElement.textContent = "2 months free";
let arcade = document.getElementsByClassName("arcade")[0];
let advanced = document.getElementsByClassName("advanced")[0];
let pro = document.getElementsByClassName("pro")[0];
let arcadePrice = document.getElementById("arcadePrice");
let advancedPrice = document.getElementById("advancedPrice");
let proPrice = document.getElementById("proPrice");
arcadePrice.textContent = "$90/year";
advancedPrice.textContent = "$120/year";
proPrice.textContent = "$150/year";
arcade.appendChild(extraContentElement.cloneNode(true));
advanced.appendChild(extraContentElement.cloneNode(true));
pro.appendChild(extraContentElement.cloneNode(true));
arcade.lastElementChild.id = "arcade-free";
advanced.lastElementChild.id = "advanced-free";
pro.lastElementChild.id = "pro-free";
document.getElementsByClassName("ball")[0].style.marginLeft = "1vw";
document.getElementById("right").style.color = "hsl(213, 96%, 18%)";
document.getElementById("left").style.color = "hsl(231, 11%, 63%)";
}
}, [toggle]);
const handleClick = () => {
if (toggle === 0) {
setToggle(1);
setInit(false);
} else {
setToggle(0);
}
};
return (
<Container>
<h1> Select your plan</h1>
<Subtitle>You have the option of monthly or yearly billing.</Subtitle>
<Flex>
<Arcade imgUrl={arcade} className="arcade">
<Title>Arcade</Title> <Price id="arcadePrice">$9/mo</Price>
</Arcade>
<Advanced imgUrl={advanced} className="advanced">
<Title>Advanced</Title>
<Price id="advancedPrice">$12/mo</Price>
</Advanced>
<Pro imgUrl={pro} className="pro">
<Title>Pro</Title>
<Price id="proPrice">$15/mo</Price>
</Pro>
</Flex>
<SwitchBar>
<Left id="left">Monthly</Left>
<Switch onClick={handleClick}>
<Ball className="ball"></Ball>
</Switch>
<Right id="right">Yearly</Right>
</SwitchBar>
<GoBack>Go Back</GoBack>
<Next>Next Step</Next>
</Container>
);
};
Actually I have a toggle switch whenever I click on that (when toggle state becomes 1) I want a extra sentence to display at the last in each of ‘arcade’,’advanced’,’pro’ components. This works fine but when I make some changes and save the file on the same toggle position (toggle=1) the statements keep on adding. If I do this on toggle=0 they start to get deleted as per the code. Maybe this is because the page re-renders on saving but is there any way to stop this as this poses great problem in debugging.
2
Answers
You can use React’s state management keeping track of added elements and only add/remove as needed when toggle changes.
Something like this as reference, do adapt to your code, this is only an example.
Edit: Since this is not how you should be using React, here is an example of how to properly use React state to store the prices and render them
You seem to completely misunderstand the way React is meant to be used. You should not use
id
,class
, or any ofgetElementsByClassName
,getElementById
,style
,textContent
,removeChild
,createElement
,cloneNode
, etc.Instead you should simply return something different depending on the current state and let React deal with DOM manipulation. Here is a cleaned up version of your code.
Note that we’re simply returning different things depending on whether
showYearly
is true or false.I renamed
toggle
toshowYearly
for clarity and removedinit
as I have no idea what it’s meant to do.For the style on
Left
,Right
andBall
, you should use transient props fromstyled-components
. For instance: