How can I call "useSate(false)" in React from a nested component? - javascript

How can I call "useSate(false)" in React from a nested component?
I would like to close the sidebar when one of the sidebar items is clicked. For that I need to call the onclick function setOpen(true) from the parent component.
function SearchDropdown() {
const [open, setOpen] = useState(false);
return (
<>
<div className="searchIcon" onClick={() => setOpen(!open)}><img src="./assets/img/SearchN.jpg" alt=" " /><p>Search</p></div>
{open && <>
<div className="searchBarDropdown"><SearchBar></SearchBar></div>
<div onClick={() => setOpen(!open)} className="searchBarDropdownX"></div>
</>}
</>
);
}
function MenuSidebar() {
const [open, setOpen] = useState(false);
return (
<>
<div className="logo" onClick={() => setOpen(true)}><p>LOgo</p><img className="dropdown" src="./assets/img/Dropdown.png" alt=">" /></div>
{open && <>
<div className="menuSidebar">
<h3 className="backwardsSection" onClick={() => setOpen(false)}>đź ” Go Back</h3>
<MenuSidebarItems />
<h3 className="sidebarTopics">Topics</h3>
<TopicItems />
</div>
<div className="menuSidebarSpacing" onClick={() => setOpen(false)}></div>
</>}
</>
);
}
function MenuSidebarItems() {
return (
<>
<MenuSidebarItem leftIcon={ <HomeIcon /> } rightIcon={ <HomeIcon></HomeIcon> }>Home</MenuSidebarItem>
<MenuSidebarItem leftIcon={ <HomeIcon /> }>Dashboard</MenuSidebarItem>
<MenuSidebarItem leftIcon={ <HomeIcon /> }>Shop</MenuSidebarItem>
<MenuSidebarItem leftIcon={ <HomeIcon /> } rightIcon={ <HomeIcon></HomeIcon> }>Projects</MenuSidebarItem>
<MenuSidebarItem leftIcon={ <HomeIcon /> }>About</MenuSidebarItem>
</>
);
}
function MenuSidebarItem(props) {
const navigate = useNavigate();
return (
<button className="menuItem" onClick={() => {
navigate("/" + props.children.toString().toLowerCase());
}}>
<span className="leftIcon">{props.leftIcon}</span>
{props.children}
<span className="rightIcon">{props.rightIcon}</span>
</button>
);
}
Thanks, Martin

You need to pass the setState that close the navbar as props to the component that display the menu.
function SearchDropdown() {
const [open, setOpen] = useState(false);
return (
<>
<div className="searchIcon" onClick={() => setOpen(!open)}><img src="./assets/img/SearchN.jpg" alt=" " /><p>Search</p></div>
{open && <>
<div className="searchBarDropdown"><SearchBar></SearchBar></div>
<div onClick={() => setOpen(!open)} className="searchBarDropdownX"></div>
</>}
</>
);
}
function MenuSidebar() {
const [open, setOpen] = useState(false);
return (
<>
<div className="logo" onClick={() => setOpen(true)}><p>LOgo</p><img className="dropdown" src="./assets/img/Dropdown.png" alt=">" /></div>
{open && <>
<div className="menuSidebar">
<h3 className="backwardsSection" onClick={() => setOpen(false)}>đź ” Go Back</h3>
<MenuSidebarItems setOpen={setOpen}/>
<h3 className="sidebarTopics">Topics</h3>
<TopicItems />
</div>
<div className="menuSidebarSpacing" onClick={() => setOpen(false)}></div>
</>}
</>
);
}
function MenuSidebarItems(props) {
const {setOpen} = props
return (
<>
<MenuSidebarItem setOpen={setOpen} leftIcon={ <HomeIcon /> } rightIcon={ <HomeIcon></HomeIcon> }>Home</MenuSidebarItem>
<MenuSidebarItem setOpen={setOpen} leftIcon={ <HomeIcon /> }>Dashboard</MenuSidebarItem>
<MenuSidebarItem setOpen={setOpen} leftIcon={ <HomeIcon /> }>Shop</MenuSidebarItem>
<MenuSidebarItem setOpen={setOpen} leftIcon={ <HomeIcon /> } rightIcon={ <HomeIcon></HomeIcon> }>Projects</MenuSidebarItem>
<MenuSidebarItem setOpen={setOpen} leftIcon={ <HomeIcon /> }>About</MenuSidebarItem>
</>
);
}
function MenuSidebarItem(props) {
const navigate = useNavigate();
const {setOpen} = props
return (
<button className="menuItem" onClick={() => {
setOpen={flase}
navigate("/" + props.children.toString().toLowerCase());
}}>
<span className="leftIcon">{props.leftIcon}</span>
{props.children}
<span className="rightIcon">{props.rightIcon}</span>
</button>
);
}

Related

Nav header moving only to two items and not going to the third item

This is the code for a navigation in tab header using an arrow icon, but its moving to only 2 items and not going to the third item.
This is the onclick function and useState
const [ActiveTab, setActiveTab] = useState("HAIRCUT");
var index = 0;
const HandleTab = (data) => {
index = (index + 1) % data.length;
console.log(data[index].category_name);
setActiveTab(data[index].category_name);
};
This is the icon and TabConatiner section
<MainRow>
{isServicesLoading || services.length === 0 || services.data === undefined ? (
<></>
) : (
<>
{" "}
{services.length !== 0 &&
services.data?.map((category) => (
<>
<div className="lefticon" style={{}}>
<img src={Left} />
</div>
<div onClick={() => HandleTab(services.data)} className="righticon">
<img src={Right} />
</div>
</>
))}
<TabContainer
defaultActiveKey="HAIRCUT"
activeKey={ActiveTab}
onSelect={() => HandleTab(services.data)}
id="services-tabs"
>
{services.length !== 0 &&
services.data?.map((category, idx) => (
<TabItem
eventKey={category.category_name}
title={
<>
<TitleContainer>
<TitleImg src={service[idx].img} />
{/* <TitleImg src={category.icon} /> */}
<H3>{category.category_name}</H3>
</TitleContainer>
<TitleContainer>
{/* <TitleImg src={service[idx].img} /> */}
</TitleContainer>
</>
}
>
<div>
<Col md={12} sm={12}>
<Link to={`/service/${category.slug}`}>
{" "}
<TabContent
className="tabservices"
service={category.service}
/>
</Link>
</Col>
</div>
</TabItem>
))}
</TabContainer>
</>
)}
</MainRow>

Ant Design modal appears few times in react js

Ant modal appears few times, but if i remove map function inside the modal then its works fine its appears only one time.
what may be the issue? please help me to solve this issue (Modal triggering/appears few times)
Ant modal code follows:
const [visibleVoucherModal, setVisibleVoucherModal] = useState(false);
const showVoucherModal = () => {
setVisibleVoucherModal(true)
}
const closeVoucherModal = () => {
setVisibleVoucherModal(false);
};
const SavedVoucherModal = () => {
return (
<Modal title="Select Any Voucher" visible={visibleVoucherModal} onCancel={closeVoucherModal} footer={null} >
{savedVoucherList.length >= 1 ?
<div>
<Checkbox.Group className="w-100" onChange={checkBox} value={voucherVal} >
{savedVoucherList.map((item, i) => {
return (
<div key={i}>
<Checkbox value={item.Id} className="w-100" onChange={e => { handleCheckBox(e, i) }}
checked={checked[i] || true} disabled={!checked[i] && disabled} >
<div className="pl-4">
<List.Item style={{ marginTop: "-35px" }} className="py-0">
<List.Item.Meta
// avatar={<img src={item.Photo == '' ? 'd' : item.Photo} alt="" width="72" />}
title={<span style={{ fontSize: "12px" }}>{item.Name}</span>}
description={<div className="small">Expiry Date: <br />{item.ExpireDate.slice(0, 10)}</div>}
/>
<div className="pt-1">
<p className="font-weight-bold text-primary mb-0">{numberFormat(item.Price)}</p>
<small><del>{numberFormat(item.OldPrice)}</del></small>
</div>
</List.Item>
</div>
</Checkbox>
<Divider className="m-0 p-0 mb-4" />
</div>)
})}
</Checkbox.Group>
</div> :
<p className="mb-4">Oops, there is no voucher applicable to this order</p>
}
<Button type="primary" className="font-weight-bold btn-round" onClick={closeVoucherModal}>Close</Button>
</Modal>
)
}
Button:
<Button type="default" className="text-primary border-right-0 border-left-0" size="large" onClick={showVoucherModal}>Redeem Voucher</Button>

react not rendering JSX inside map function

I'm trying to run a loop then render JSX content :
The console.log is rendering right data but the return does not render html content
const StaticTable = (props) => {
const [data, setData] = useState({});
useEffect(() => {
const { audio, ...newData } = props.data;
setData(newData);
}, []);
return (
<>
<Button content="Add" primary />
<div>
{Object.keys(data).map((keyName, i) => {
data[keyName].map((elm) => {
console.log(elm);
return (
<Flex key={i.toString()} gap="gap.small">
<Header as="h5" content={new Date(keyName).getDay()} />
<Header as="h5" content="Start Date" />
<p>{data[keyName]}</p>
<Flex>
<Dropdown
items={timeoptions}
placeholder="Start Time"
defaultValue={elm.start}
checkable
getA11ySelectionMessage={{
onAdd: (item) => `${item} has been selected.`,
}}
/>
<div style={{ margin: "10px 0px" }}>
<Dropdown
items={timeoptions}
placeholder="End Time"
defaultValue={elm.end}
checkable
getA11ySelectionMessage={{
onAdd: (item) => `${item} has been selected.`,
}}
/>
</div>
</Flex>
<Header as="h5" content="End Date" />
</Flex>
);
});
})}
</div>
</>
);
};
I got empty html
const StaticTable = (props) => {
const [data, setData] = useState({});
useEffect(() => {
const { audio, ...newData } = props.data;
setData(newData);
}, []);
return (
<>
<Button content="Add" primary />
<div>
{Object.keys(data).map((keyName, i) => {
return (
<Flex key={i} gap="gap.small">
<Header as="h5" content={new Date(keyName).getDay()} />
<Header as="h5" content="Start Date" />
<p>{keyName}</p>
<Flex>
<Dropdown
items={timeoptions}
placeholder="Start Time"
defaultValue={keyName.start}
checkable
getA11ySelectionMessage={{
onAdd: (item) => `${item} has been selected.`,
}}
/>
<div style={{ margin: "10px 0px" }}>
<Dropdown
items={timeoptions}
placeholder="End Time"
defaultValue={keyName.end}
checkable
getA11ySelectionMessage={{
onAdd: (item) => `${item} has been selected.`,
}}
/>
</div>
</Flex>
<Header as="h5" content="End Date" />
</Flex>
);
});
})}
</div>
</>
);
};

React Hooks : Change state of multiple items

I have a list of icons.
When I click on one of them, I want it to :
1/ change state to day or night
2/ change icon image to a sun or a moon.
But with the code that I've written, if I click on one, it changes all the icons image and only one state is linked to all.
How can I do so each icons has it own state and when i click on icon, only the icon clicked changes to a moon or a sun and not all of them ?
My code :
export default function MyModal() {
const [isVisible, setVisible] = useState(false);
const [isDay, setDay] = useState(true);
const { RangePicker } = DatePicker;
const { Option } = Select;
const style = {
verticalAlign: "middle",
marginRight: 10,
};
function handleDayNight() {
isDay === true ? setDay(false) : setDay(true);
console.log("isDay =", isDay);
}
function handleSelectChange(value) {
console.log(`selected ${value}`);
}
function handleCheckChange(checkedValues) {
console.log("checked =", checkedValues);
}
return (
<div>
<Button type="primary" onClick={() => setVisible(true)}>
Add an exception
</Button>
<Modal
title="Add an exception"
style={{ top: 20 }}
visible={isVisible}
onOk={() => setVisible(false)}
onCancel={() => setVisible(false)}
>
<p>Exceptions name</p>
<Input placeholder="80% Wednesday" />
<p style={{ marginTop: 10 }}>Select date</p>
<RangePicker onChange={([date]) => console.log(date)} />
<p style={{ marginTop: 10 }}>Frequency</p>
<Select
defaultValue="Weekly"
style={{ width: 120 }}
onChange={handleSelectChange}
>
<Option value="daily">Daily</Option>
<Option value="weekly">Weekly</Option>
<Option value="monthly">Monthly</Option>
</Select>
<Divider />
<Checkbox.Group style={{ width: "100%" }} onChange={handleCheckChange}>
<div>
{isDay === true ? (
<Sun style={style} onClick={handleDayNight} />
) : (
<Moon style={style} onClick={handleDayNight} />
)}
<Checkbox value="Monday">Monday</Checkbox>
<br></br>
{isDay === true ? (
<Sun style={style} onClick={handleDayNight} />
) : (
<Moon style={style} onClick={handleDayNight} />
)}
<Checkbox value="Tuesday">Tuesday</Checkbox>
<br></br>
{isDay === true ? (
<Sun style={style} onClick={handleDayNight} />
) : (
<Moon style={style} onClick={handleDayNight} />
)}
<Checkbox value="Wednesday">Wednesday</Checkbox>
<br></br>
{isDay === true ? (
<Sun style={style} onClick={handleDayNight} />
) : (
<Moon style={style} onClick={handleDayNight} />
)}
<Checkbox value="Thursday">Thursday</Checkbox>
<br></br>
<Checkbox value="Friday">Friday</Checkbox>
<br></br>
<Checkbox value="Saturday">Saturday</Checkbox>
<br></br>
<Checkbox value="Sunday">Dimanche</Checkbox>
</div>
</Checkbox.Group>
</Modal>
</div>
);
}
Use a separate component for each of those, so you can have individual separate states inside those components. Eg, replace all of
{isDay === true ? (
<Sun style={style} onClick={handleDayNight} />
) : (
<Moon style={style} onClick={handleDayNight} />
)}
with
<SunMoon style={style} />
const SunMoon = ({ style }) => {
const [isDay, setDay] = useState(true);
const handleDayNight = () => setDay(!isDay);
return isDay
? <Sun style={style} onClick={handleDayNight} />
: <Moon style={style} onClick={handleDayNight} />;
};

How to use multiple material ui dialog with React?

I want to use two dialog in sign up page and login page.
the implement that I want to do are signup screen showing up when click to sign up button on the Top page, and login screen showing up when click to login Button on signup page.
I wrote open state on App.js.
but the trouble is when it's written in App.js, two of modal open..
Does anyone know how to settle it?
App.js
const App = () => {
const [open, setOpen] = useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Top handleClickOpen={handleClickOpen}/>
<SignupModal open={open} handleClose={handleClose} />
<LoginModal open={open} handleClose={handleClose} />
</div>
)
Top.js
const Top = (props) => {
const classes = useStyles();
return (
<React.Fragment>
<div style={style}>
<Button variant="outlined" className={classes.loginButton} onClick={props.handleClickOpen}>
Login
</Button>
</div>
<h1>Toppage</h1>
</React.Fragment>
);
}
SignupModal.js
const SignupModal = (props) => {
return (
<div>
<Dialog
open={props.open}
onClose={props.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title" className={classes.title}>Sign up</DialogTitle>
<DialogContent className={classes.content}>
<div className={classes.text}>
<TextField id="standard-basic" label=“name” fullWidth/>
<TextField id="standard-basic" label=“email” fullWidth/>
<TextField id="standard-basic" label=“password” fullWidth/>
<TextField id="standard-basic" label=“pass”word fullWidth/>
</div>
</DialogContent>
<p className={classes.toLogin}>to Login</p>
<DialogActions>
<Button onClick={props.handleClose} className={classes.signUpButton}>
Send
</Button>
</DialogActions>
</Dialog>
</div>
);
}
LoginModal.ls
const LoginModal = (props) => {
return (
<div>
<Dialog
open={props.open}
onClose={props.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title" className={classes.title}>Login</DialogTitle>
<DialogContent className={classes.content}>
<div className={classes.text}>
<TextField id="standard-basic" label=“name” fullWidth/>
<TextField id="standard-basic" label=“pass”word fullWidth}/>
</div>
</DialogContent>
<DialogActions>
<Button onClick={props.handleClose} className={classes.signUpButton}>
Login
</Button>
</DialogActions>
</Dialog>
</div>
);
}
export default LoginModal
You are sharing the state on both of your modals that's why.
The solution is simple, have 2 states; one that will determine if SignupModal is opened or not and another one for LoginModal.
const App = () => {
const [openLogin, setOpenLogin] = useState(false);
const [openSignup, setOpenSignup] = useState(false);
return (
<div>
<Top
onClickLogin={() => setOpenLogin(true)}
onClickSignup={() => setOpenSignup(true)}
/>
<SignupModal open={openLogin} handleClose={() => setOpenLogin(false)} />
<LoginModal open={openSignup} handleClose={() => setOpenSignup(false)} />
</div>
);
};
const Top = (props) => {
return (
<React.Fragment>
<div>
<Button
variant="outlined"
className={classes.loginButton}
onClick={props.onClickLogin}
>
Login
</Button>
<Button
variant="outlined"
className={classes.loginButton}
onClick={props.onClickSignup}
>
Signup
</Button>
</div>
<h1>Toppage</h1>
</React.Fragment>
);
};

Categories