How to efficiently toggle classes with multiple HTML elements across multiple files - javascript

I am toggling an arrow image whenever my div is clicked. I am controlling the state of the click with
const [toggleArrow, setToggleArrow] = useState(false)
My div has an onClick function that controls the state and toggles the faq-subject-toggle-arrow class that adds an image
<div className={`faq-subject ${toggleArrow ? 'faq-subject-toggle-arrow' : ''}`} onClick={() => {
setToggleArrow(!toggleArrow)
}>
My problem is that I have 50 divs across multiple styles and don't want to make 50 states to toggle one image.
Is there a more efficient solution for this with less code?

I created something that does the same thing. I extracted your code and made a component. now the state lives inside the component and will not affect others.
live demo
component
import { useState } from "react";
export const Button = () => {
const [toggleArrow, setToggleArrow] = useState(false);
return (
<div
style={{ width: "50px", height: "50px", margin: "10px" }}
className={`faq-subject ${toggleArrow ? "faq-subject-toggle-arrow" : ""}`}
onClick={() => {
setToggleArrow(!toggleArrow);
}}
></div>
);
};
css file, I didn't have the same classes so I created mine.
.faq-subject {
background: blue;
}
.faq-subject-toggle-arrow {
background: orange;
}
now you can use it wherever you want for multiple times
import { Button } from "./button";
import "./styles.css";
export default function App() {
return (
<div className="App">
<Button />
<Button />
<Button />
<Button />
<Button />
</div>
);
}

Related

How to pass var from jsx to pure css file in react js?

I want to pass var form parent component to child component (--my-custom) that will set color for child component , but when i write like this it gives me error , if you see i use my custom variable in MyButton.css in this manner it will adjust my button to any color i want.
// my jsx file
import React from "react";
import "./styles/MyButton.css";
const MyButton = ({ title, handelClick, color }) => {
return (
<div class="parentbutton">
<a class="mybutton" onClick={() => handelClick()} style={{ --my-custom: color }}>
<span>{title}</span>
<i></i>
</a>
</div>
);
};
export default MyButton;
//MyButton.css
a.mybutton:hover {
letter-spacing: 0.25em;
background-color: var(--my-custom);
box-shadow: 0 0 2.5em var(--my-custom);
color: var(--my-custom);
}
You can replace your style like this, it might works!
<div style={{ "--my-css-var": 10 } as React.CSSProperties} />
Just use the inline styling without a .css file
import React from "react";
const MyButton = ({ title, handelClick, color }) => {
return (
<div className="parentbutton">
<a className="mybutton" onClick={() => handelClick()} style={{
backgroundColor: color,
boxShadow: `0 0 2.5em ${color}`,
color: color
}}>
<span>{title}</span>
<i></i>
</a>
</div >
);
};
export default MyButton;

I created a Modal using createPortal() method to render it. Then I found that modal renders twice

When the button inside the Post clicked, Popup will render with createPortal method outside from root element's tree.
With this code that popup renders twice.
I want to render it only once.
Here's the parent Post component.
import { useState } from 'react';
import PopupModal from './PopupModal/PopupModal';
import './Post.css';
const Post = (props) => {
const postData = props;
const [isOpen, setIsOpen] = useState(false);
return (
<div className="post-container">
<div className="post-img-container">
<img className="post-img" src={props.img} alt="Travels" />
</div>
<div className="post-text-container">
<h4 className="post-heading">{props.title}</h4>
<p className="post-para">{props.description}</p>
<h1 className="post-price">{props.price}</h1>
<div className="post-btn-container">
<button onClick={() => setIsOpen(true)} className="post-btn">
Check Availability
</button>
<PopupModal dataData={postData} open={isOpen} onClose={() => setIsOpen(false)}>
Button123
</PopupModal>
</div>
</div>
</div>
);
};
export default Post;
And here's the popupModal
import React from 'react';
import ReactDOM from 'react-dom';
import '../PopupModal/popupModal.css'
const MODAL_STYLES = {
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%,-50%)',
background: '#fff',
width: '40vw',
height: '90vh',
padding: '50px',
zIndex: 1000,
};
const PopupModal = ({ open, children, onClose ,dataData }) => {
if (!open) return null;
console.log('xxx');
console.log(dataData);
return ReactDOM.createPortal(
<>
<div className='modal-overlay' ></div>
<div className='modal-container'>
<button onClick={onClose}> Popup Close</button>
{children}
</div>
</>,
document.getElementById('portal')
);
};
export default PopupModal;
Here's how I figured it rendered twice.
Here's the Popup with overlay around it which covers the background.
Thanks in advance!
Try following
{
isOpen && <PopupModal dataData={postData} open={isOpen} onClose={() => setIsOpen(false)}>
Button123
</PopupModal>
}

I want to change display of a div when clicked -React Styled Component

I am creating a div using styled component. I want to change the visibility of the div on button clicked,
const Category = () => {
const [showCategory, setShowCategory] = useState(false)
useEffect(() => {
setShowCategory(false)
}, [])
return (
<button onClick={() => { setShowCategory(true)}}>
New Category
</button>
<AdminInputStyle>
<form>
<form-group>
<label>Add Category</label>
<input type='text' />
</form-group>
<button>Submit</button>
</form>
</AdminInputStyle>
)
}
Here's the styled component
const AdminInputStyle = styled.div`
display: ${(d) => (d.showCategory ? 'show' : 'hidden')};
`
You can try something like this too, show when you need to show the add category when you press add category
return (
<>
<button
onClick={() => {
setShowCategory(true);
}}
>
New Category
</button>
{showCategory && (
<AdminInputStyle>
<form>
<form-group>
<label>Add Category</label>
<input type="text" />
</form-group>
<button>Submit</button>
</form>
</AdminInputStyle>
)}
</>
);
I have an example, but in the case we will use a Button. Clicking it will alter the visibility.
You must pass a property to the styled component if you want it to be visible based on that prop. In your example, you don't pass a prop to the styled component in this scenario, which is why the component cannot detect if it should be visible or not.
You will need to / can use the css function from the styled-components library. This can help you return styles based on the properties your styled-component will have. In this example, our property that we pass to the button will be called visible.
import React from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'styled-components/macro';
const StyledButton = styled.button`
border-radius: 3px;
color: white;
background-color: green;
cursor: pointer;
width: 100px;
height: 50px;
${({ visible }) => {
return css`
visibility: ${visible ? 'visible' : 'hidden'};
`;
}}
`;
export default function Button({ children, visible, onClick }) {
return (
<StyledButton visible={visible} onClick={onClick}>
{children}
</StyledButton>
);
}
Button.propTypes = {
children: PropTypes.node,
visible: PropTypes.bool,
onClick: PropTypes.func,
};
You can see that passing the visible prop will enable the button to alter its' styles based on whether that property is true or false. We utilize a function within the component that returns the css function and this will control the visibility css property.
Here is how we utilize the button and pass props to it from another component; in this example just the App.js file:
import React, { useState } from 'react';
import './App.css';
import Button from './components/Button';
function App() {
const [visible, setVisible] = useState(true);
function handleClick() {
setVisible(!visible);
}
return (
<div className="App">
<Button visible={visible} onClick={handleClick}>
Click
</Button>
</div>
);
}
export default App;
FYI: For the css; you don't want display: hidden;. hidden is an invalid value for the display prop. You'd want display: none; if you don't want the element to be in the DOM. visibility: hidden; will add the element to the DOM, but it won't be visible. You can use whichever works best for your case 👍🏿

How do i change the color of a button when clicked in react? [duplicate]

This question already has an answer here:
How to change background color of button onClick in react js?
(1 answer)
Closed 1 year ago.
I am new to react and i am trying to use the useState hook to change the color of a button when clicked. Please how do i go about it . Here is the code below
import { Button } from 'bootstrap'
import React, { useState } from 'react'
import "../workout/style.css"
const [buttonColor, setButtonColor] = useState()
function Workout() {
let buttonColor = document.getElementsByClassName("button")
return (
<div>
<div class="container">
<button className="button">BODYWEIGHT</button>
<button className="button">BARBELL</button>
<button className="button">DUMBELLS</button>
<button className="button">KETTLEBELLS</button>
<button className="button">STRETCHES</button>
</div>
</div>
)
}
export default Workout
Here are a few examples of two ways to color button backgrounds onClick:
const { useState } = React;
function App() {
const [btnClass, setBtnClass] = useState(false);
const [btnColor, setBtnColor] = useState("red");
return (
<div className="App">
<button
onClick={() => {
btnClass ? setBtnClass(false) : setBtnClass(true);
}}
className={btnClass ? "btnClass clicked" : "btnClass"}
>
button
</button>
<button
onClick={() => {
btnColor === "red" ? setBtnColor("green") : setBtnColor("red");
}}
style={{ backgroundColor: btnColor }}
>
button
</button>
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
.App {
font-family: sans-serif;
text-align: center;
}
.btnClass {
background-color: red;
}
.btnClass.clicked {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
https://codesandbox.io/s/focused-cloud-m0qqx?file=/src/styles.css:0-148
The states in react are special variables.
They work like constants so when you assign a value, it wont change at all.
And when you set a new value with the setState function, (the only way to change the value btw) the component rerender.
So, to answer your question... Apply an onClick property to a button.
<div>
<div class="container">
<button className="button" onClick={()=> setButtonColor(newColor)} style={{backgroundColor: `${buttonColor}`}}>BODYWEIGHT</button>
<button className="button">BARBELL</button>
<button className="button">DUMBELLS</button>
<button className="button">KETTLEBELLS</button>
<button className="button">STRETCHES</button>
</div>
</div>
Bear in mind that buttonColor the waybi used this code, would take values like 'red', 'blue ' ... ect
Please check useEfect or SetState, i recommend UseEfect for this case.
go to documentation for more information https://reactjs.org/docs/hooks-state.html
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
remember add bem on your component and load this.

React - Changing CSS property on click (arrow function)

I have the following in one of my React / Gatsby files:
import React from "react"
const click = () => {
console.log("J");
}
const NavButton = () =>
<button className="navbar-toggler navbar-toggler-right" style={{backgroundColor: 'blue', position: "absolute", margin: "30px"}}type="button" data-toggle="collapse" data-target="#collapsingNavbar" onClick={click}>
<div id="nav-icon1">
<span></span>
<span></span>
<span></span>
</div>
</button>
const Dropdown = () =>
<div style={{visibility: "hidden", backgroundColor: "blue", position: "absolute", height: "100%", width: "100%"}}>
</div>
export default (props) =>
<div className="left col-xs-12 col-md-6">
<Dropdown />
<NavButton />
{props.children}
</div>
Now I would like to fire click() whenever somebody presses the NavButton, and then I would like to make Dropdown visible. How would I do this? Right now I have it hardcoded that Dropdown has style={{visibility: "hidden", ....
I'm also wondering whether I am doing this correctly, having everything loosely in these different functions, if somebody could tell me that would be great!
Your controlling class needs to be stateful: it needs to maintain the boolean state as to whether the dropdown is open or closed. When rendering the dropdown, if the boolean is open, then you'll show the dropdown, else you won't.
Here is your code rewritten to do this. Note the child components take props as arguments. This is how the parent communicates with them. Some of those props are callbacks, this is how the child communicates back to the parent.
import React from "react"
const NavButton = ({onClick}) =>
<button className="navbar-toggler navbar-toggler-right" style={{backgroundColor: 'blue', position: "absolute", margin: "30px"}}type="button" data-toggle="collapse" data-target="#collapsingNavbar" onClick={onClick}>
<div id="nav-icon1">
<span></span>
<span></span>
<span></span>
</div>
</button>
const Dropdown = ({show}) =>
<div style={{visibility: show ? "visible" : "hidden", backgroundColor: "blue", position: "absolute", height: "100%", width: "100%"}}>
</div>
export default class Parent extends React.Component {
state = {
dropdownVisible: false,
};
// toggles the dropdown each time it is called
toggleDropdown = () => this.setState(state => ({
dropdownVisible: !state.dropdownVisible,
}));
render() {
return (
<div className="left col-xs-12 col-md-6">
<Dropdown show={this.state.dropdownVisible} />
<NavButton onClick={this.toggleDropdown} />
{this.props.children}
</div>
);
}
}

Categories

Resources