adding and removing a classList in react js - reactjs

I am using functional component in react js , in the below code
the class right-panel-active is not being added / is undefined. Someone help to enable the class be added when the button is toggled
import React from 'react';
import './style.css';
import {
Modal,
DropdownMenu
} from '../MaterialUI';
/**
* #author
* #function Header
**/
const Header = (props) => {
const container = () => {
document.getElementById('container');
}
const signUpButton = () => {
container.classList.add('right-panel-active');
};
const signInButton = () => {
container.classList.remove('right-panel-active');
};
return (
<div className="header">
<div className="container" id="container">
<button className="ghost" id="signIn" onClick={signInButton} >Sign In</button>
</div>
<div className="overlay-panel overlay-right">
<p>Enter your personal details and start journey with us</p>
<button className="ghost" id="signUp" onClick={signUpButton} >Sign Up</button>
</div>
</div>
)
}
export default Header

You are not utilising any of React's functionality.
Read about state management in React
and Event Handlers in React
const Header = (props) => {
const [isContainerActive, setIsContainerActive] = React.useState(false);
const signUpButton = () => {
setIsContainerActive(false);
};
const signInButton = () => {
setIsContainerActive(true);
};
return (
<div className="header">
<div id="container" className={`container${isContainerActive ? " right-panel-active" : ""}`}>
<button className="ghost" id="signIn" onClick={signInButton}>Sign In</button>
</div>
<div className="overlay-panel overlay-right">
<p>Enter your personal details and start journey with us</p>
<button className="ghost" id="signUp" onClick={signUpButton}>Sign Up</button>
</div>
</div>
);
}
ReactDOM.render(<Header />, document.getElementById("root"));
.header {height: 120px;}
.container {float:left;}
.overlay-right {display: none;background: red;float:right;height:100%;}
.right-panel-active ~ .overlay-right {display: inline-block;}
<div id="root"></div>
<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>
PS: I also recommend https://www.npmjs.com/package/classnames , or the cx library for className management.

I think the best solution for this is to making a state and handle the style by a ternarian
function Welcome(props) {
const {name} = props;
return (
<h1 style={name === 'Sara' ? right-panel-active : right-panel-inactive}>Hello, {name}</h1>
)}
function App() {
return (
<div>
<Welcome name="Sara" />
</div>
);
}

This is the React way of doing,
You have to keep a local state (useState) and track the button click and based on the state change update the class to the container. You shouldn't directly change the DOM.
Click on the button to see the CSS is adding or not.
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [isSignUp, setSignUp] = useState(true);
return (
<div id="container" className={isSignUp ? "right-panel-active" : ""}>
<button onClick={() => setSignUp(false)}>SignIn</button>
<button onClick={() => setSignUp(true)}>SignUp</button>
//for testing the change
{isSignUp ? "right-panel-active added" : "right-panel-active removed"}
</div>
);
}
Sample working code - https://codesandbox.io/s/fragrant-http-qo6du?file=/src/App.js

No need to add click event with vanilla js, you could add an React onClick event. You forgot to return the container.
// if you use curly braces you must return the value
const container = () => {
return document.getElementById('container');
};
// or skip the curly braces
const container = () =>
document.getElementById('container');

Related

How can we create a editable `<code>` tag on fly and add different attributes to that

On click on Code button, how can we create a editable <code> tag on fly and add different attributes in react web app ?
Or may be an editable field display as code tag ? Could someone please advise here ?
import React, { useState } from 'react';
import { useNavigate } from "react-router-dom";
const Admin = () => {
const [createCode, setCreateCode] = useState("");
const navigate = useNavigate();
const createCodeSection = () => {
const newElement = React.createElement('code', {key: 'ele'+ new Date().getTime(), className:'codehighlight'}, `--sample code to enter-- `,);
setCreateCode(createCode => [...createCode, newElement]);
}
const handleLogout = () => {
localStorage.removeItem('loginEmail');
navigate("/login");
};
return (
<div id="App">
<div className='adminSection'>
<div className='row'>
<div className="logout">
<img src="/images/logout.png" alt="Logout" onClick={handleLogout}></img>
</div>
<div className='createBlogSection'>
<div className='row'>
<button onClick={createCodeSection}>Code</button>
<button>Image</button>
<button>Code</button>
</div> <br></br>
<textarea>
{createCode}
</textarea>
</div>
</div>
</div>
</div>
)
}
export default Admin;
css:
.codehighlight{
background-color: #353232;
color: #fff;
}

React change css style of a div in another component by button clicking in another component

on my Project I have a banner on top of my site with 2 buttons. when I click the button profile I want it to change the css style of a div in another component.
this is my code for the banner:
import Profile from "./Profile";
function Banner() {
const invis=false;
return (
<div className="banner">
<span className="bannerbtnsettings">
<button className="btnbannersettings">Settings</button>
</span>
<span className="bannerbtnprofile">
<button className="btnbannerprofile" onClick={Profile.changeStyle}>Profile</button>
</span>
</div>
);
}
export default Banner;
this is my code for the div in the other component:
import "../index.css";
import React, { useState } from "react";
const Profile = () => {
const [style, setStyle] = useState("profile-hidden");
const changeStyle = () => {
console.log("you just clicked");
setStyle("profile-displayed");
};
return (
<div>
<div className={style}> hellllo</div>
</div>
);
};
export default Profile;
I can only find information about this with parent-child components.
They said I should use a usestate import but I can't seem to get it working. what's the proper way to do this?
All you need is lift your state to parent component, if you have a long trip to your common ancestor you can try to use a context. Attached a working example. Hope it helps!
const Banner = ({ onClickHandler }) => {
return (
<div className="banner">
<span className="bannerbtnsettings">
<button className="btnbannersettings">Settings</button>
</span>
<span className="bannerbtnprofile">
<button className="btnbannerprofile" onClick={() => onClickHandler()}>Profile</button>
</span>
</div>
)}
const Profile = ({ style }) => {
return (
<div>
<div className={style}>I'm your profile :)</div>
</div>
);
};
const App = () => {
// We lift the state
const [style, setStyle] = React.useState("profile-hidden");
const profileHandler = () => {
setStyle(style === 'profile-hidden'
? 'profile-displayed'
: 'profile-hidden')
}
return(
<div>
<Banner onClickHandler={profileHandler} />
<Profile style={style} />
</div>
)
}
// Render
ReactDOM.createRoot(
document.getElementById("root")
).render(
<App />
);
.profile-hidden {
display: none;
}
.profile-displayed {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
<div id="root"></div>
You cannot use this syntax for React Components COMPONENT.method
, in your case onClick={Profile.changeStyle} !
Instead you should make Banner parent component and use Profile component as child inside it or vise versa !
then You should pass the state style as props so then you will be able to use its value.
your code should look like this :
function Banner() {
const [style, setStyle] = useState("profile-hidden");
const changeStyle = () => {
console.log("you just clicked");
setStyle("profile-displayed");
};
return (
<div className="banner">
<span className="bannerbtnsettings">
<button className="btnbannersettings">Settings</button>
</span>
<span className="bannerbtnprofile">
<button className="btnbannerprofile" onClick={changeStyle}>Profile</button>
</span>
<Profile style={style} />
</div>
);
}
export default Banner;
and your Profile component :
const Profile = (props) => {
return (
<div>
<div className={props.style}> hellllo</div>
</div>
)
}

How to change a style of an HTML element in React?

I have two React components
class App extends React.Component {
render() {
return (
<div id="appWrapper">
<ConfigureWindow />
<button id="configureClocksButton">Configure clocks</button>
<section id="clocksHere"></section>
</div>
);
}
}
const ConfigureWindow = () => (
<div id="configureWindowWrapper">
<div id="configureWindow">
<section id="addCitySection">TODO: adding a city</section>
<div id="verticalLine"></div>
<section id="listOfCities">
<header>
<h1>Available cities</h1>
<div id="closeConfigureWindowWrapper">
<img src="..\src\images\exit.png" id="closeConfigureWindow" alt="" />
</div>
</header>
<section id="availableCities"></section>
</section>
</div>
</div>
);
I want "ConfigureWindow" to be shown when "configureClocksButton". I tried to execute it with props, state and a function but got errors. It also would be nice if you explain me how to create new React components with React functions?
You probably want to use the React.JS event onClick (https://reactjs.org/docs/handling-events.html), and a state to store the action. To create a function component, you just have to return the JSX you want to render, and use hooks (https://reactjs.org/docs/hooks-intro.html) and then do a conditional rendering (https://reactjs.org/docs/conditional-rendering.html):
const App = () => {
const [toggleConfiguration, setToggleConfiguration] = useState(false)
return (
<div id="appWrapper">
{toggleConfiguration && <ConfigureWindow />}
<button onClick{() => setToggleConfiguration(true)} id="configureClocksButton">Configure clocks</button>
<section id="clocksHere"></section>
</div>
);
}
It's a bit difficult to understand your post, but I gather you want to click the button with id="configureClocksButton" and conditionally render the ConfigureWindow component.
You can accomplish this with some boolean state, a click handler to toggle the state, and some conditional rendering.
class App extends React.Component {
this.state = {
showConfigureWindow: false,
}
toggleShowConfigureWindow = () => this.setState(prevState => ({
showConfigureWindow: !prevState.showConfigureWindow,
}))
render() {
return (
<div id="appWrapper">
{showConfigureWindow && <ConfigureWindow />}
<button
id="configureClocksButton"
onClick={this.toggleShowConfigureWindow}
>
Configure clocks
</button>
<section id="clocksHere"></section>
</div>
);
}
}
A function component equivalent:
const App = () => {
const [showConfigureWindow, setShowConfigureWindow] = React.useState(false);
const toggleShowConfigureWindow = () => setShowConfigureWindow(show => !show);
return (
<div id="appWrapper">
{showConfigureWindow && <ConfigureWindow />}
<button
id="configureClocksButton"
onClick={toggleShowConfigureWindow}
>
Configure clocks
</button>
<section id="clocksHere"></section>
</div>
);
}

Trying to change React Style attribute by changing state hook

Transform is not updating the style component below. I have console logged the state to ensure that it is changing and it was, just not the style component (it kept the color red).
import React, {useState} from 'react';
const Carousel = () => {
let [selectedIndex, setSelectedIndex] = useState(0)
const [cellCount,] = useState(9);
let [transform, setTransform] = useState({color: 'red'});
const prevButton = () => {
setSelectedIndex(selectedIndex-1);
setTransform({color: 'green !important'})
console.log(selectedIndex)
console.log(transform)
};
const nextButton = () => {
setSelectedIndex(selectedIndex+1);
setTransform({color: 'red !important'})
console.log(transform)
}
return (
<>
<div className="scene">
<div style={transform} className="carousel">
<div className="carousel__cell">1</div>
<div className="carousel__cell">2</div>
<div className="carousel__cell">3</div>
<div className="carousel__cell">4</div>
<div className="carousel__cell">5</div>
<div className="carousel__cell">6</div>
<div className="carousel__cell">7</div>
<div className="carousel__cell">8</div>
<div className="carousel__cell">9</div>
</div>
</div>
<button onClick={prevButton}>
Previous
</button>
<button onClick={nextButton}>
Next
</button>
</>
)
}
React inline style doesn't know the !important property. There is usually always a way to avoid using it, and it is better to do so.
If you just don't avoid using !important, it will work here.
If you have to set it, this would work:
import React, { useState } from 'react';
const Carousel = () => {
let [selectedIndex, setSelectedIndex] = useState(0);
let [transform, setTransform] = useState({ color: 'red' });
const prevButton = () => {
setSelectedIndex(selectedIndex - 1);
setTransform({ ...{ color: 'green' } });
// rotateCarousel();
console.log(selectedIndex);
console.log(transform);
};
const nextButton = () => {
setSelectedIndex(selectedIndex + 1);
setTransform({ ...{ color: 'red' } });
console.log(transform);
// rotateCarousel();
};
return (
<>
<div className="scene">
<div
ref={el => {
if (el) {
el.style.setProperty('color', transform.color, 'important');
}
}}
className="carousel"
>
<div className="carousel__cell">1</div>
{transform.color}
<div className="carousel__cell">2</div>
<div className="carousel__cell">3</div>
<div className="carousel__cell">4</div>
<div className="carousel__cell">5</div>
<div className="carousel__cell">6</div>
<div className="carousel__cell">7</div>
<div className="carousel__cell">8</div>
<div className="carousel__cell">9</div>
</div>
</div>
<button onClick={prevButton}>Previous</button>
<button onClick={nextButton}>Next</button>
{transform.color}
</>
);
};
export default Carousel;

React.js - Disable background scroll when a modal is showing

I am trying to disable the background body scroll when a modal pop up window is open. I created the Modal using React portal. The only way I can think of doing this is by giving the body an overflow-y property when the Modal is open, but am unsure how to execute this..
my Modal.js looks like this
export default function Modal({open, onClose, image, title, description}){
if (!open) return null
return ReactDom.createPortal(
<>
<div id="overlay" />
<div id="modal" >
<button title={title} onClick={onClose}>close</button>
<h3>{title}</h3>
<img src={image} className="modal-img"/>
{description}
</div>
</>,
document.getElementById('portal')
)
}
and the component where I am 'rendering' the model
const ProjectCardUI = (props)=>{
const[isOpen, setIsOpen] = useState(false)
function openModal() {
setIsOpen(true)
// can I set the styling for '.body' or 'html' here?
}
return(
<div className="card text-center container-fluid d-flex">
<a className="modal-click" onClick ={openModal}>this is a link</a>
<Modal
open={isOpen}
onClose={() => setIsOpen(false)}
title={props.cardName}
image={props.imgsrc}
description={props.cardDescription}>
</Modal>
</div>
)
};
any help would be great.
You can directly manipulate the body style via the document object.
For example:
import React from "react";
import ReactDOM from "react-dom";
export default function Test() {
const setHidden = () => {
console.log(document.body.style.overflow);
if (document.body.style.overflow !== "hidden") {
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "scroll";
}
};
return (
<div>
<button onClick={setHidden}>Click me! </button>
<h1>1</h1>
<h1>2</h1>
<h1>3</h1>
<h1>4</h1>
<h1>5</h1>
<h1>6</h1>
<h1>7</h1>
<h1>8</h1>
<h1>9</h1>
<h1>10</h1>
<h1>11</h1>
<h1>12</h1>
<h1>13</h1>
<h1>14</h1>
<h1>15</h1>
<h1>16</h1>
</div>
);
}
ReactDOM.render(<Test />, document.getElementById("container"));
Maybe something like this:
const ProjectCardUI = (props) => {
const [isOpen, setIsOpen] = useState(false);
function openModal() {
setIsOpen(true);
// can I set the styling for '.body' or 'html' here?
}
useEffect(() => {
const body = document.querySelector('body');
body.style.overflow = isOpen ? 'hidden' : 'auto';
}, [isOpen])
return (
<div className="card text-center container-fluid d-flex">
<a className="modal-click" onClick={openModal}>
this is a link
</a>
<Modal
open={isOpen}
onClose={() => setIsOpen(false)}
title={props.cardName}
image={props.imgsrc}
description={props.cardDescription}
></Modal>
</div>
);
};

Resources