How to pass CSS class names in React JS - reactjs

I want to change the width of a component whenever I click a button from another component
This is the button in BiCarret:
import { useState } from "react";
import { BiCaretLeft } from "react-icons/bi";
const SideBar = () => {
const [open, setOpen] = useState(true);
return (
<div className="relative">
<BiCaretLeft
className={`${
open ? "w-72" : "w-20"
} bg-red-400 absolute cursor-pointer -right-3 top-5 border rounded-full`}
color="#fff"
size={25}
onClick={setOpen(!true)}
/>
</div>
);
};
export default SideBar;
and this is the component I want to change the width on click
import "./App.css";
import SideBar from "./components/SideBar/SideBar";
function App() {
return (
<div className="app flex">
<aside className="h-screen bg-slate-700"> // change the width here
<SideBar />
</aside>
<main className="flex-1 h-screen"></main>
</div>
);
}
export default App;

You have two simple solutions, either:
Create context
Crete context and store Open value in it, change it on click and in App react to it.
Dom manipulation
In app add ID to element you would like to change and onClick in the other component use document.getElementById(THE_ID).classList.add("new-class-for-increased-width") which gets the DOM element and adds class to it.

Related

The Side-Bar Menu is rendered by its own

The sidebar is automatically rendered even i have functionality to implement with click on pizza icon
Main.js component , in this component the functionality of useState Hook for toggling the sidebar is implemented
import React, { useState } from 'react';
import { Navbar } from '../NavBar/Navbar';
import { SideBar } from '../SideBar/sidebar';
import { MainContainer,MainContent,MainItem,MainH1,MainP1,MainButton } from './MainElements';
export const Main = () => {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => {
setIsOpen(!isOpen);
};
return (
<MainContainer>
<Navbar toggle={toggle}/>
<SideBar isOpen={isOpen} toggle={toggle} />
<MainContent>
<MainItem>
<MainH1>
Greatest Pizza Ever
</MainH1>
<MainP1>
Ready as early in the 5 Minutes
</MainP1>
<MainButton>Submit</MainButton>
</MainItem>
</MainContent>
</MainContainer>
)
}
Sidebar.js component which is automatically rendered on the screen
import { SidebarContainer,Icon,CloseIcon,SidebarMenu,SidebarLink,SidebarBtn,SidebarRoute } from "./sidebar.element";
export const SideBar = ({isOpen,toggle})=> {
return(
<SidebarContainer isOpen={isOpen} onClick={toggle}>
<Icon onClick={toggle}>
<CloseIcon/>
</Icon>
<SidebarMenu>
<SidebarLink to="/">Pizzas</SidebarLink>
<SidebarLink to="/">Desserts</SidebarLink>
<SidebarLink to="/"> Full Menu</SidebarLink>
</SidebarMenu>
<SidebarBtn>
<SidebarRoute to="/">Order Now</SidebarRoute>
</SidebarBtn>
</SidebarContainer>
);
}
Navbar.js component which holds the icon and props toggle
import React from 'react';
import { Nav, NavLink, NavIcon, PizzaIcon} from './NavbarElements';
export const Navbar = ({toggle}) => {
return (
<Nav>
<NavLink to='/'>
Muncheese
</NavLink>
<NavIcon onClick={toggle}>
<p>Menu</p>
<PizzaIcon/>
</NavIcon>
</Nav>
)
}
Not so sure what your isOpen do. Did you declare that part inside SidebarContainer?
Try changing it to render conditionally like this
{ isOpen ? <SideBar toggle={toggle}/> : null }
Also its worth pointing out that within your sidebar, you've already set an onClick event listener for the whole sidebar component. The onClick within your Icon is not necessary unless you want a specific part of this component to perform the toggle function then you need to remove the onClick in SidebarContainer.
<SidebarContainer isOpen={isOpen} onClick={toggle}>

Why inline styling doesnt work in react on components?

Why inline styling doesnt work in react on components?I dont understand why this is not working.I know is possible to make it different ways.(with css files for example).Im just corius.The intellisense does not help by inline styling either.Its strange..
import "./App.css";
import Button from "./components/Button";
function App() {
return (
<div className="App" >
<Button style={{fontSize:"50px"}} />
</div>
);
}
export default App;
//this is from Button components
import React from "react";
const Button = () => {
return (
<div>
<button>
Change
</button>
</div>
);
};
export default Button;
You need to pass the style property to the Button component:
const Button = ({style}) => {
return (
<div>
<button style={style}>
Change
</button>
</div>
);
};

how to use react routing to switch between pages

i am currently building a shopping website . i finished the homepage and i have to make routing for other pages
i have 3 main files: App.js, Menuitem.js (which is to execute props), and Homepage.js (which also is used to apply executing props from sections array which includes titles and background images and sections paths)
this is the App js
import React from "react";
import Homepage from './Homepage'
import "./styles.css";
import './Homepage.css'
import {Route, Switch} from "react-router-dom";
const Hatspage=function() {
return(
<div>
<h1>
Hats page
</h1>
</div>
)
}
function App() {
return (
<div>
<Switch>
<Route exact path='/'component={Homepage}/>
<Route path='/hats'component={Hatspage}/>
</Switch>
</div>
);
}
export default App
Menuitem.js
import React from 'react'
import {WithRouter} from 'react'
const Menuitem= function(props){
return(
<div className='card' style={{ backgroundImage: `url(${props.imageUrl})` }} >
<div className='text-frame'>
<h1 className='title'>{props.title}</h1>
<p className='subtitle'>shop now</p>
</div>
</div>
)
}
export default Menuitem
Homepage.js
import React from "react";
import sections from './directory-components';
import Menuitem from "./menu-item-components";
const arrayOne=[sections.slice(0,3)]
const arrayTwo=[sections.slice(3,)]
function extract(item){
return(
<Menuitem
title={item.title} imageUrl={item.imageUrl}/>
)
}
function Homepage(){
return(
<div className='directory-menu'>
<div className='content'>
{sections.slice(0,3).map(extract) }
</div>
<div className='second'>
{sections.slice(3,).map(extract) }
</div>
</div>
)
}
export default Homepage
so i need for example when i click on hats picture i switch to hats page . how to do that
image attached
Thanks in advance
reactjs routing
You can do two different approaches. Both of them will require an extra prop that will be the actual url you want to access when clicking the menu item.
Assuming you modify your section array to look like this:
[{title: 'Your title', imageUrl: 'your-image.jpg', linkUrl: '/hats'}]
And you modify your extract function to add the url value as a prop in the MenuItem component:
function extract(item){
return(
<Menuitem
title={item.title} imageUrl={item.imageUrl} linkUrl={item.linkUrl} />
)
}
You can do this
First one: Using a Link component from react router:
import React from "react";
import { Link } from "react-router-dom";
const Menuitem= function(props){
return(
<Link to={props.linkUrl}>
<div className='card' style={{ backgroundImage: `url(${props.imageUrl})`
}} >
<div className='text-frame'>
<h1 className='title'>{props.title}</h1>
<p className='subtitle'>shop now</p>
</div>
</div>
</Link>
)
}
Now you will have to add extra styling because that will add a regular a tag, but I like this approach because for example you can open the link in a new tab since it is a regular link.
Using the history prop.
import React from "react";
import { useHistory } from "react-router-dom";
const Menuitem= function(props){
const history = useHistory()
const goToPage = () => history.push(props.linkUrl)
return(
<div className='card' style={{ backgroundImage: `url(${props.imageUrl})`
}} onClick={goToPage} >
<div className='text-frame'>
<h1 className='title'>{props.title}</h1>
<p className='subtitle'>shop now</p>
</div>
</div>
)
}
This approach is a basic on click so if you press the component it will go to the selected page, this will work but keep in mind that event bubbling will be harder if you add more on clicks inside the menu item, so please be aware of that.
You should fire an event inside your MenuItem in order to redirect the user
import { useHistory } from 'react-router-dom'
const history = useHistory()
<img onClick={() => history.push('/hats')} />

How to toggle class of a div element by clicking on a button that is inside another functional component (another file)?

I want to toggle class of container (file 2) by an onClick on the button that is inside another component file.
The button has already an onClick function and I want to make it so it calls on two functions. Two toggle functions for the button and two class toggles for the container.
Hope it makes sense.
Here is my code so far:
Button component (File 1)
import React, {useState} from "react";
import "./Sort.scss";
const Sort = () => {
const [toggleSortIcon, toggleSortIconSet] = useState(false);
return (
<div className="tools">
<button
onClick={() => toggleSortIconSet(!toggleSortIcon)}
className={`sort ${toggleSortIcon ? "horizontal" : "vertical"}`}>
</button>
</div>
);
}
export default Sort;
Div container component that I want to change the class of (File 2)
import React, {useState} from "react";
import "./WordContainer.scss";
import UseAnimations from "react-useanimations";
const WordContainer = ({title, definition, example}) => {
const [toggleSize, toggleSizeState] = useState(false);
return (
<div className={`container ${toggleSize ? "big" : "small"}`}>
<div className="content">
<h2>{title}</h2>
<p>{definition}</p>
<h3>Example</h3>
<p>{example}</p>
</div>
<img onClick={() => toggleSizeState(!toggleSize)} src="./resize.svg" alt="resize" className="resize"/>
<div className="bookmark">
<UseAnimations
animationKey="bookmark"
size={26}
/>
</div>
</div>
);
}
export default WordContainer;
You could either have a global state management system (redux, or with custom hooks) that you can use to store the icon size.
Or you could simply provide a callback to your component that stores the icon size in a parent component that then feeds it back to your
Something like this:
const [size, setSize] = useState(/* default value */);
render() {
<>
<Sort onSizeToggle={setSize} />
<WordContainer size={size} />
</>
}

How to use React hooks to determine if sidebar should show?

I have read some introductions on React Hooks and want to make a simple app with a button in the header component, which determines if the main app should show the sidebar. The button sets the variable showSidebar in the header, and I want to read it again within my main component. The code for actually showing the sidebar is stripped out for brevity.
This is index.js:
import React, { useState } from "react";
import ReactDOM from "react-dom";
import Header from "./header";
import "./styles.css";
function App() {
const [showSidebar, setShowSidebar] = useState(true);
return (
<div className="App">
<Header />
<h1>Sidebar toggler</h1>
<p>
Should I show sidebar? <b>{showSidebar.toString()}</b>
</p>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
And this is the header.js:
import React, { useState } from "react";
export default function Header() {
const [showSideBar, setShowSidebar] = useState(true);
const toggleSidebar = () => setShowSidebar(!showSideBar);
return (
<header>
Button in header toggles sidebar:
<button onClick={() => toggleSidebar()}>
Toggle sidebar (state: {showSideBar.toString()})
</button>
</header>
);
}
I am new to React, but do not understand why the state does not update in index.js? I also made a CodeSandbox with the code.
useState is stores local state, for comparison you can think of it similar to setState in a class component (although in reality they aren't exactly equivalent). Therefore, setting setShowSidebar in App won't reflect the same value as that set in Header and vice versa.
It doesn't look like Header needs any form of local state if it's simply changing state of the outer component, you can pass in an event handler and any relevant state Header needs as props instead
index.js
function App() {
const [showSidebar, setShowSidebar] = useState(true);
const toggleSidebar = useCallback(() => setShowSidebar(value => !value));
return (
<div className="App">
<Header onClick={toggleSidebar} showSideBar={showSidebar} />
<h1>Sidebar toggler</h1>
<p>
Should I show sidebar? <b>{showSidebar.toString()}</b>
</p>
</div>
);
}
header.js
export default function Header(props) {
return (
<header>
Button in header toggles sidebar:
<button onClick={props.onClick}>
Toggle sidebar (state: {props.showSideBar.toString()})
</button>
</header>
);
}
What you're doing wrong is declaring a separate state in Header which you shouldn't do, because it has nothing to do with parent's state. Pass the parent state and a callback to update the parent state as a props to the header. Pass showSidebar as props to the Header component:
import React, { useState } from "react";
import ReactDOM from "react-dom";
import Header from "./header";
import "./styles.css";
function App() {
const [showSidebar, setShowSidebar] = useState(true);
return (
<div className="App">
// Pass prop here
<Header
showSidebar={showSidebar}
toggleSidebar={()=>{setShowSidebar(!showSidebar)}}
/>
<h1>Sidebar toggler</h1>
<p>
Should I show sidebar? <b>{showSidebar.toString()}</b>
</p>
</div>
);
}
// and then in your Header,
export default function Header(props) {
return (
<header>
Button in header toggles sidebar:
<button onClick={props.toggleSideBar}>
Toggle sidebar (state: {props.showSideBar.toString()})
</button>
</header>
);
}
You want to keep state showSidebar in the parent component (where you need to read it) and pass the functionality to change it to the header component (where you need to change showSidebar)
To do move toggleSidebar to index.js
const toggleSidebar = () => setShowSidebar(!showSideBar);
and pass the function to the Header component like this
<Header toggleSidebar={toggleSidebar} />
now invoke it on clickEvent in Header component like this
<button onClick={() => toggleSidebar()}>
remember to include the prop in your Header component
export default function Header({toggleSidebar}) {
You should have your toggleSidebar function in App.js itself, and pass toggleSidebar function and showSidebar state in Header component as props.
App.js
function App() {
const [showSidebar, setShowSidebar] = useState(true)
const toggleSidebar = () => setShowSidebar(!showSidebar)
return (
<div className="App">
<Header showSideBar={showSidebar} onClick={toggleSidebar} />
<h1>Sidebar toggler</h1>
<p>
Should I show sidebar? <b>{showSidebar.toString()}</b>
</p>
</div>
)
}
Header.js
import React from 'react'
export default function Header(props) {
return (
<header>
Button in header toggles sidebar:
<button onClick={props.onClick}>
Toggle sidebar (state: {props.showSideBar.toString()})
</button>
</header>
)
}
Demo

Resources