How to set className to div in ReactJS using functional component - reactjs

I have following code:
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [border, setBorder] = useState(false);
return (
<div className="App">
<div className="SectionTitleItem">Claimers</div>
<div className="SectionTitleItem">Resources</div>
</div>
);
}
CodeSandbox
How can I set the border-bottom only for the active item?

App.js
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [active, setActive] = useState(true);
return (
<div className="App">
<div onClick={() => setActive(true)} className={`SectionTitleItem${active ? " active" : ""}`}>Claimers</div>
<div onClick={() => setActive(false)} className={`SectionTitleItem${!active ? " active" : ""}`}>Resources</div>
</div>
);
}
styles.css
.App {
font-size: 18px;
margin: 40px 0 32px 0;
display: flex;
}
.SectionTitleItem {
margin-left: 50px;
}
.SectionTitleItem.active {
border-bottom: 2px solid red;
}

Perhaps something like
export default function App() {
const [active, setActive] = useState(null);
const getItemClassName = (name) => {
if (name === active) {
return "SectionTitleItem active";
}
return "SectionTitleItem";
};
return (
<div className="App">
<div
onClick={() => setActive("claimers")}
className={getItemClassName("claimers")}
>
Claimers
</div>
<div
onClick={() => setActive("resources")}
className={getItemClassName("resources")}
>
Resources
</div>
</div>
);
}
.App {
font-size: 18px;
margin: 40px 0 32px 0;
display: flex;
}
.SectionTitleItem {
margin-left: 50px;
}
.SectionTitleItem.active {
border-bottom: 2px solid red;
}

Related

How can I do conditional rendering on a styled component?

I am using conditional rendering to make toggle function. But I think there is a problem with the method because I did conditional rendering on the styled component but it doesn't work. Can you tell me how to fix it? I'd appreciate it if you let me know thanks
my.jsx:
If I click on another image, the value of the profile becomes false, and if I click on the profile image, the value of the profile becomes true. And according to the value of the profile, I gave the value of the display by conditional rendering the tag whose className is IconWrap6True. But now, the display value of IconWrap6Trued keeps coming out as block, and 'none' is not applied. The cord is long, so I skipped the parts that I didn't need
import React, { useState } from 'react'
import styled from 'styled-components';
import defaultProfile from '../resources/images/img/defaultprofile.jpg'
const NavigationBarWrap1 = styled.div`
position: fixed;
flex-direction: column;
box-sizing: border-box;
display: flex;
flex-shrink: 0;
align-items: stretch;
.IconWrap6True {
${props => props.profile ? "block" : "none"};
box-sizing: border-box;
border-bottom-left-radius: 50%;
top: 50%;
border-top-right-radius: 50%;
left: 50%;
border: 2px solid rgb(38,38,38);
transform: translate(-50%,-50%);
}
`
function NavigationBar() {
//state
const[home, setHome] = useState(true);
const[profile,setProfile] = useState(true);
//true
const setTrueHome = () => {
setHome(true)
}
const setTrueProfile = () => {
setProfile(true)
}
//false
const setFalseHome = () => {
setHome(false)
}
const setFalseProfile = () => {
setProfile(false)
}
//handle
const forHome = (e) => {
setTrueHome();
setFalseProfile();
}
const forProfile = (e) => {
setFalseHome();
setTrueProfile();
}
return (
<NavigationBarWrap1>
<div className='IconWrap'>
<div className='IconWrap4'>
<div onClick={forHome} className='IconWrap5'>
<div>
<div className='IconWrap6'>
<div className='IconWrap7'>
{home===true?
<>
<img/>
</>:
<>
<img/>
</>}
</div>
</div>
</div>
</div>
</div>
</div>
<div className='IconWrap'>
<div className='IconWrap2'>
<div>
<div className='IconWrap6'>
<div profile={profile} className='IconWrap6True'/>
<div onclick={forProfile} className='IconWrap7'>
<img src={defaultProfile}/>
</div>
</div>
</div>
<div className='textWrap'>
<div className='textWrap2'>
<div className='textWrap3'>
프로필
</div>
</div>
</div>
</div>
</div>
</NavigationBarWrap1>
)
}
export default NavigationBar;
pass the profile prop to NavigationBarWrap1
<NavigationBarWrap1 profile={profile}>

Unable to view custom sidebar component created with react router in storybook

I am quite new to React and have been trying to create a custom sidebar component. Based on my understanding by going through different tutorials, this is what I have so far:
react-router-dom version: ^6.3.0
storybook: ^6.1.17
These are my components
sidebar.jsx
const SidebarNav = styled.nav`
background: #15171c;
width: 250px;
height: 100vh;
display: flex;
justify-content: center;
position: fixed;
top: 0;
right: ${({ sidebar }) => (sidebar ? "0" : "-100%")};
transition: 350ms;
z-index: 10;
`;
const SidebarWrap = styled.div`
width: 100%;
`;
const Sidebar = () => {
const [sidebar, setSidebar] = useState(true);
return (
<>
<IconContext.Provider value={{ color: "#fff" }}>
<SidebarNav sidebar={sidebar}>
<SidebarWrap>
{sideBarData.map((item, index) => {
return <SubMenu item={item} key={index} />;
})}
</SidebarWrap>
</SidebarNav>
</IconContext.Provider>
</>
);
};
export default Sidebar;
sidebardata.jsx
export const sideBarData = [ {
title: "Question 4",
path: "/test"
},
// {
// title: "Question 5",
// path: "/testing"
// }
];
sidebarsubmenu.jsx
import React, { useState } from "react";
import { Link } from "react-router-dom";
import styled from "styled-components";
const SidebarLink = styled(Link)`
display: flex;
color: #e1e9fc;
justify-content: space-between;
align-items: center;
padding: 20px;
list-style: none;
height: 60px;
text-decoration: none;
font-size: 18px;
&:hover {
background: #252831;
border-left: 4px solid green;
cursor: pointer;
}
`;
const SidebarLabel = styled.span`
margin-left: 16px;
`;
const DropdownLink = styled(Link)`
background: #252831;
height: 60px;
padding-left: 3rem;
display: flex;
align-items: center;
text-decoration: none;
color: #f5f5f5;
font-size: 18px;
&:hover {
background: green;
cursor: pointer;
}
`;
const SubMenu = ({ item }) => {
const [subnav, setSubnav] = useState(false);
const showSubnav = () => setSubnav(!subnav);
return (
<>
<SidebarLink to={item.path}
onClick={item.subNav && showSubnav}>
<div>
{item.icon}
<SidebarLabel>{item.title}</SidebarLabel>
</div>
<div>
{item.subNav && subnav
? item.iconOpened
: item.subNav
? item.iconClosed
: null}
</div>
</SidebarLink>
{subnav &&
item.subNav.map((item, index) => {
return (
<DropdownLink to={item.path} key={index}>
{item.icon}
<SidebarLabel>{item.title}</SidebarLabel>
</DropdownLink>
);
})}
</>
);
};
export default SubMenu;
BookSideBarLayout.jsx
import React from 'react';
import Sidebar from './BookSideBar';
function Layout(props) {
return (
<div>
<div style={{display: "flex"}}>
<Sidebar/>
</div>
</div>
);
}
export default Layout;
BookSidebarRoutes.jsx
import React from "react";
import {BrowserRouter, Route,Routes} from "react-router-dom";
import Support from "./Support";
import Layout from "./BookSideBarLayout";
function MyRoutes() {
return (
<BrowserRouter>
<Layout/>
<Routes>
{/* <Route path="/" element={<Sidebar/>}/> */}
<Route path="/test" element={<Support/>}/>
</Routes>
</BrowserRouter>
);
}
export default MyRoutes;
The story that I created was as below
import { storiesOf } from '#storybook/react';
import StoryRouter from 'storybook-react-router';
import MyRoutes from '../../src/components/BookSidebarRoutes';
// export default {
// title: 'Side Bar',
// //decorators : [(Story) => (<MemoryRouter><Story/></MemoryRouter>)]
// };
storiesOf('Params', module)
.addDecorator(StoryRouter())
.add('params', () => (
<MyRoutes/>
));
export const Default = () => <MyRoutes />;
After I run my story above, I keep getting the error as below:
A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.**
I also tried Switch in the MyRoutes component but that too didn't work. Any guidance in this will be really helpful. Thank you in advance

React Navbar Hamburger Icon unable to be Positioned Absolutely to Right

I'm making a React navbar with a hamburger menu icon, but I cannot figure out why my icon cannot be positioned absolutely to the right. Chrome dev tools indicates that both Top and Right properties (as well as any other margin/padding properties) are invalid property values on my hamburger icon (a div element), though my nav menu itself is able to be positioned absolutely to the right.
Navbar.jsx:
import React, { useState } from 'react';
import NavIcon from './NavIcon';
import NavMenu from './NavMenu';
import './navbar.css';
const Navbar = () => {
const [isOpen, setIsOpen] = useState('false');
return (
<nav>
<NavIcon isOpen={isOpen} setIsOpen={setIsOpen} />
<NavMenu isOpen={isOpen} setIsOpen={setIsOpen} />
</nav>
);
};
export default Navbar;
NavMenu.jsx:
import React from 'react';
import NavItem from './NavItem';
import './navbar.css';
const NavMenu = ({ isOpen }) => {
const slideIn = {
transform: () => isOpen ? 'translateX(1)' : 'translateX(0)'
};
return (
<ul className='Navbar__menu' isOpen={isOpen} style={slideIn}>
<NavItem title='Home' />
<NavItem title='About' />
<NavItem title='Contact' />
</ul>
);
};
export default NavMenu;
NavIcon.jsx:
import React from 'react';
import './navbar.css';
const NavIcon = ({ isOpen, setIsOpen }) => {
const toXTop = {
transform: isOpen ? 'rotate(-45deg) translate(-5.25px, 6px)' : 'none'
};
const toXMid = {
opacity: isOpen ? '0' : '1'
};
const toXbottom = {
transform: isOpen ? 'rotate(45deg) translate(-5.25px, -6px)' : 'none'
};
return (
<div className='Navbar__icon' isOpen={isOpen} onClick={() => setIsOpen(!isOpen)}>
<div className='Navbar__icon--bars' style={toXTop} />
<div className='Navbar__icon--bars' style={toXMid} />
<div className='Navbar__icon--bars' style={toXbottom} />
</div>
);
};
export default NavIcon;
NavItem.jsx:
import React from 'react';
import './navbar.css';
const NavItem = ({ title }) => {
return (
<div className='Navbar__menu--item'>
{ title }
</div>
);
};
export default NavItem;
navbar.css:
.Navbar__icon {
display: block;
position: absolute;
top: 5;
right: 5;
z-index: 1;
cursor: pointer;
}
.Navbar__icon--bars {
width: 25px;
height: 4px;
background-color: #666;
border-radius: 5px;
margin: 4px 0;
transition: 0.2s;
}
.Navbar__menu {
position: absolute;
width: 15em;
height: auto;
right: 0;
list-style: none;
background-color: #000;
}
.Navbar__menu--item {
font: 1rem Arial, sans-serif;
color: #999;
margin: 1em;
cursor: pointer;
}
App.js just renders the Navbar.jsx component.
Any advice is appreciated. Thanks.
It seems that Top/Left/Right/Bottom property values in React do not support unitless numerical values, as this issue was resolved by adding px units to my values.

Adding A button before the previousLabel Props and after the nextLabel Props in React-Paginate Not Working

Please I needed to add a button before the previousLabel property details and after the nextLabel prop details in React-Paginate but what I have below is not working. I have also tried to read the documentation and check all the prop details but still couldn't achieve the result below.
I want a first button to come before one button and a last button to come after the next button.
what the code below looks like above.
what I want to achieve below
```
import React, { useState, useEffect } from 'react'
import axios from 'axios'
import ReactPaginate from 'react-paginate';
import './styles.css'
export default function App() {
const [postsPerPage] = useState(5);
const [offset, setOffset] = useState(1);
const [posts, setAllPosts] = useState([]);
const [pageCount, setPageCount] = useState(0)
const getPostData = (data) => {
return (
data.map(post => <div className="container" key={post.id}>
<p>User ID: {post.id}</p>
<p>Title: {post.title}</p>
</div>)
)
}
const getAllPosts = async () => {
const res = await axios.get(`https://jsonplaceholder.typicode.com/posts`)
const data = res.data;
const slice = data.slice(offset - 1 , offset - 1 + postsPerPage)
// For displaying Data
const postData = getPostData(slice)
// Using Hooks to set value
setAllPosts(postData)
setPageCount(Math.ceil(data.length / postsPerPage))
}
const handlePageClick = (event) => {
const selectedPage = event.selected;
setOffset(selectedPage + 1)
};
useEffect(() => {
getAllPosts()
}, [offset])
return (
<div className="main-app">
{/* Display all the posts */}
{posts}
{/* Using React Paginate */}
<ReactPaginate
previousLabel={"previous"}
nextLabel={"next"}
breakLabel={"..."}
breakClassName={"break-me"}
pageCount={pageCount}
onPageChange={handlePageClick}
containerClassName={"pagination"}
subContainerClassName={"pages pagination"}
activeClassName={"active"} />
</div>
);
}
```
Below is the css
.main-app {
margin: 2% 10%;
border: 1px ridge #464141;
padding: 5%;
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
font-size: 20px;
color: #464141;
}
.container {
border-bottom: #fff 2px ridge;
}
.pagination {
margin-top: 45px;
margin-left: -40px;
display: flex;
list-style: none;
outline: none;
}
.pagination>.active>a {
background-color: #47ccde;
color: #fff;
}
.pagination>li>a {
border: 1px solid #47ccde;
padding: 5px 10px;
outline: none;
cursor: pointer;
}
.pagination>li>a, .pagination>li>span {
color: #47ccde;
background-color: azure;
}

React axios get return empty array

As I mentioned, console.log print only empty array. I think the problem will related with async problem.
This is the error what I got.
So, I make delay in axios, return with isLoading but still not working.
Has any solution? Thanks for help!
Test.js(parent component, every state in here) -> MainTest.js -> Question.js
Test.js
import React, { useState, useEffect } from "react";
import Tutorial from "../Tutorial";
import MainTest from "../MainTest";
import axios from "axios";
const Test = () => {
const [count, setCount] = useState(0);
const [questionNum, setQuestionNum] = useState(0);
const [questionList, setQuestionList] = useState([]);
useEffect(() => {
axios.get("http://localhost:3001/get/question").then((response) => {
setQuestionList(response.data);
})
}, []);
const questionHandler = () => {
setQuestionNum(questionNum + 1);
setCount(count + 1);
};
return (
<div>
<MainTest
questionList={questionList}
questionNum={questionNum}
questionHandler={questionHandler}
/>
</div>
);
};
export default Test;
MainTest.js
import React from 'react'
import styled from 'styled-components'
import ProgBar from './ProgBar'
import Question from './Question'
import SelectSec from './SelectSec'
function MainTest({questionList, questionNum, questionHandler}) {
return (
<TestWrap>
<ProgBar />
<Question questionList={questionList[questionNum]}/>
<SelectSec questionList={questionList[questionNum]} questionHandler={questionHandler}/>
</TestWrap>
)
}
export default MainTest
const TestWrap = styled.div`
width: 100vh;
height: 100vh;
background-image: url("./images/background/background.png");
`;
Question.js
import React from "react";
import Styled from "styled-components";
function Question({questionList}) {
console.log(questionList)
return (
<QuestionWrap>
<i className="far fa-calendar-alt"></i>
<h3>
{questionList.question.split('</br>').map(line => {
return(<>{line}<br/></>)
})}
</h3>
</QuestionWrap>
);
}
export default Question;
const QuestionWrap = Styled.div `
width: 100%;
height: 55%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
i{
color: #b56467;
font-size: 2rem;
margin-bottom: 2rem;
}
h3 {
text-align: center;
font-family: "UhBeeBEOJJI";
color: #3a1a00;
font-size: 2.7rem;
line-height: 3.4rem;
}
`;
in your Question component you need to had a condition in the return like:
function Question({questionList}) {
console.log(questionList)
return (
<QuestionWrap>
<i className="far fa-calendar-alt"></i>
<h3>
{questionList & questionList.question && questionList.question.split('</br>').map(line => {
return(<>{line}<br/></>)
})}
</h3>
</QuestionWrap>
);
}
export default Question;

Resources