Code:-
const [myButtons, setmyButtons] = useState([]);
setmyButtons(response.data.Rundowns);//api using axios
let idx = [];
let [myDivs, setmyDivs] = useState([]);
const handleClick = (val, id) => {
idx.push(id);
console.log(idx);
const newArr = [...flipDivs];
console.log("newA", newArr);
newArr[idx].show = !flipDivs[idx].show;
console.log("flipDivs", flipDivs)
setFlipDivs(newArr);
};
myButtons.map((val, i) =>
`My Div # ${val}`
)
myDivs = [...Array(2).keys()].map(i => `My Div # ${i + 1}`);
const [flipDivs, setFlipDivs] = useState([
...myDivs.map(
(text, id) => ({ id, text, show: false })
)
]);
return (
<div className="allDivs">
<div style={{ color: "white" }}> Fixed Div </div>
{
flipDivs.filter(({ show }) => !!show).map(
({ text, id, show }, idx) => (
<div
key={idx}
className="simpleMargin rightBorder"
style={{ color: "white" }}
>
{text}
</div>
)
)
}
</div>
<div className="buttons">
{myButtons.map((val, id) => {
// console.log("myButtons",val);
return (
<Fragment key={id}>
<button
id={id}
className="simpleMargin"
onClick={() => handleClick(val, id)}
>
{val}
</button>
</Fragment>
)
})}
</div>
)
getting the btn name as according the api I fetch but when i click the button getting the Show in image below:-
when i added the myDivs = myButtons.map(i => ${i});
getting nothing to display
so I want that when I click the button same same will appear in div location.
How can i do that?
I am fetching the button name from api.
Please help.
Related
**> This is my Gallery Component **
import React, {useState} from 'react';
import useFirestore from '../hooks/useFirestore';
import { motion } from 'framer-motion';
const Gallery = ({ setSelectedImg }) => {
const { docs } = useFirestore('images');
here im setting the state as a Tags array
const [tags, setTags] = useState([""]);
const addTag = (e) => {
if (e.key === "Enter") {
if (e.target.value.length > 0) {
setTags([...tags, e.target.value]);
e.target.value = "";
}
}
};
functions for adding and removing Tags
const removeTag = (removedTag) => {
const newTags = tags.filter((tag) => tag !== removedTag);
setTags(newTags);
};
return (
<>
<div className="img-grid">
{docs && docs.map(doc => (
< motion.div className="img-wrap" key={doc.id}
layout
whileHover={{ opacity: 1 }}s
onClick={() => setSelectedImg(doc.url)}
>
here Im adding the Tag input to each Image...the problem is that when adding a Tag is added to all the pictures. I want to add the tags for the image that I´m selecting.
<div className="tag-container">
{tags.map((tag, ) => {
return (
<div key={doc.id} className="tag">
{tag} <span onClick={() => removeTag(tag)}>x</span>
</div>
);
})}
<input onKeyDown={addTag} />
</div>
<motion.img src={doc.url} alt="uploaded pic"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 1 }}
>
</motion.img>
</motion.div>
))}
</div>
</>
)
}
export default Gallery;
The tags array that you are using to store values entered by the user are not unique with respect to each image item. Meaning, every image item in your program is using the same instance of the tags array, what you need to do is
Either create an object that stores an array of tags for each image:
const [tagsObj, setTagsObj] = {}, then while adding a new tag for say image_1, you can simply do setTagsObj(prevObj => {...prevObj, image_1: [...prevObj?.image_1, newTagValue]},
Or create an Image Component which would then handle tags for a single image:
Gallery Component:
{
imageList.map(imageEl =>
<ImageItem key={imageEl} image={imageEl} />
)
}
ImageItem Component:
import {useState} from 'react';
export default function ImageItem({image}) {
const [tags, setTags] = useState([]);
const addTag = (e) => {
if (e.key === "Enter") {
const newVal = e.target.value;
if (newVal.length > 0) {
setTags(prevTags => [...prevTags, newVal]);
e.target.value = '';
}
}
};
const removeTag = (removedTag) => {
setTags(prevTags => prevTags.filter((tag) => tag !== removedTag));
}
return (
<div style={{margin: '12px', padding: '12px', width: '100px', height:'100px', display:'flex', flexDirection: 'column', alignItems:'center'}}>
<span>{image}</span>
{tags.map((tag, index) => {
return (
<div key={tag+index}>
{tag} <span onClick={() => removeTag(tag)}>x</span>
</div>
);
})}
<input onKeyDown={addTag} />
</div>
);
}
Refer this sandbox for ease, if available Gallery unique image tags sandbox
I suggest using the second method, as it is easy to understand and debug later on.
I hope this helps, please accept the answer if it does!
So I have those cards on the link right now. When the favorite button is clicked it will appear under FAVORITES. I wanted those cards under FAVORITES to be on the local storage, and when I "unfavorite" the cards, they should also be removed from the local storage. But how exactly do I do that? Should I use useEffect()?
Codesandbox: https://codesandbox.io/s/broken-fast-kgyzvc?file=/src/App.js
App.js
export default function App() {
const [all, setAll] = useState(true);
const [favorites, setFavorites] = useState(false);
const showAll = () => {
setAll(true);
setFavorites(false);
};
const showFavorite = () => {
setFavorites(true);
setAll(false);
};
const [dataSource, setDataSource] = useState(data);
const onFavorite = (cardId) => {
const newDataSource = [...dataSource];
const foundCardData = newDataSource.find((card) => card.id === cardId);
if (!foundCardData) return;
foundCardData.isFavorite = !foundCardData.isFavorite;
setDataSource(newDataSource);
};
return (
<div className="App">
<div className="button-group">
<button className={all ? "all active" : "all"} onClick={showAll}>
ALL
</button>
<button
className={favorites ? "favorites active" : "favorites"}
onClick={showFavorite}
>
FAVORITES
</button>
</div>
<br />
<Masonry
breakpointCols={3}
className="my-masonry-grid"
columnClassName="my-masonry-grid_column"
>
{all &&
dataSource.map((item) => (
<Cards
key={item.id}
text={item.text}
isFavorite={item.isFavorite}
onFavorite={() => onFavorite(item.id)}
/>
))}
{favorites &&
dataSource
.filter((item) => item.isFavorite === true)
.map((filtered) => (
<Cards
key={filtered.id}
text={filtered.text}
isFavorite={filtered.isFavorite}
onFavorite={() => onFavorite(filtered.id)}
/>
))}
</Masonry>
</div>
);
}
Cards.js
const Cards = ({ text, isFavorite, onFavorite }) => {
return (
<div className="cards">
<p>{text}</p>
<button onClick={onFavorite}>
{isFavorite ? "Added to Favorites!" : "Favorite"}
</button>
</div>
);
};
I just wan't to hide show more posts button if there aren't any posts. so I created showLoad function and isLoad state but I have no idea how to use this.
the show button is on the isLoad ? section. thank you for your help!
posts.tsx
const [loadMore, setLoadMore] = useState<number>(4);
const [activeMenu, setActiveMenu] = useState<string>("All");
const [isLoad, setIsLoad] = useState(false);
function getFilteredList() {
if (activeMenu === "All") {
return projectschema;
}
return projectschema.filter(
(project) => project.categories.title === activeMenu
);
}
const showMoreItems = () => {
setLoadMore((prevValue) => prevValue + 4);
};
useEffect(() => {
const showLoadButton = () => {
if (loadMore > 4) {
setIsLoad(true);
}
};
showLoadButton();
}, [loadMore]);
const filteredList = useMemo(getFilteredList, [activeMenu, projectschema]);
{filteredList.slice(0, loadMore).map((project) => (
<Link
key={project._id}
>
<section className={styles.project__item}>
test
</section>
</Link>
))}
{isLoad ? (
<>
<div className={styles.load__more}>
<div className={styles.load__icon} onClick={showMoreItems}>
<SVGCustomIcon name="LoadMore" />
</div>
</div>
</>
) : (
""
)}
you don't need to use isLoad state, you can check if the filteredList.length > 4 and loadMore <= filteredList.length), so your loadMore icon will be showed otherwise hidden.
{((filteredList.length > 4) && (loadMore <= filteredList.length)) ? (
<>
<div className={styles.load__more}>
<div className={styles.load__icon} onClick={showMoreItems}>
<SVGCustomIcon name="LoadMore" />
</div>
</div>
</>
) : (
""
)}
I have this Little list that should show different modals based on what the user select , and the problem is When I select the first time it doesn't work and I have to click on it again to work .
Here is my code :
const Mylist = props => {
const [open2, setOpen2] = React.useState(false);
const [open3, setOpen3] = React.useState(false);
const handleClose2 = () => {
setOpen2(false);
};
const handleOpen2 = () => {
setOpen2(true);
};
const handleClose3 = () => {
setOpen3(false);
};
const handleOpen3 = () => {
setOpen3(true);
};
const [isActive , SetIsActive] = useState(false);
const option =["Paid" , "UnPaid"]
return (
<div>
<i class="fas fa-ellipsis-v" onClick={(e) => SetIsActive(!isActive)}></i>
{isActive && (
<div>
{option.map((option) => (
<div
onClick={(e) => {
SetIsActive(false);
{option == 'Paid' && setOpen2(true)}
{option == 'UnPaid' && setOpen3(true)}
}}
>
{option}
</div>
))}
<Modal onClose={handleClose2} open={open2} >
<div>
Content
</div>
</Modal>
<Modal onClose={handleClose3} open={open3} >
<div>
Content
</div>
</Modal>
Your code block is a bit messy with some brackets and closing tags missing (possibly some of the code was not copied in by mistake?).
In any case, I did my best at trying to fill in the missing parts and did some refactoring to your code. I hope that fixes your bug!
import React, { useState } from 'react';
const MyList = (props) => {
const [isOpen1, setIsOpen1] = useState(false);
const [isOpen2, setIsOpen2] = useState(false);
const [isActive, setIsActive] = useState(false);
const openOption = (option) => {
setIsActive(false);
if (option === "Paid") {
setIsOpen1(true);
}
if (option === "UnPaid") {
setIsOpen2(true);
}
};
const options =["Paid", "UnPaid"]
return (
<div>
<i class="fas fa-ellipsis-v" onClick={() => setIsActive(!isActive)}></i>
{isActive && (
<div>
{options.map((option) => (
<div onClick={() => openOption(option)}>
{option}
</div>
))}
</div>
)}
<Modal onClose={() => setIsOpen1(false)} open={isOpen1} >
<div>
Content
</div>
</Modal>
<Modal onClose={() => setIsOpen2(false)} open={isOpen2} >
<div>
Content
</div>
</Modal>
</div>
);
};
i trying to make a history.push on button click
i have this search bar that will show the names of doctors when serched {suggestion.firstname}
i am trying to pass {suggestion.id } as url when cliked on the li corresponding
but here when i type and if the {suggestion.firstname} first letter comes then it automaticaly is redirecting when typing in the input field.
finddoctor is working like onchange funtion but i have written onclick funtion
function finddoctor(e) {
console.log(e);
history.push(`/detiled/${e} `);
}
const onChange = (event) => {
const value = event.target.value;
setInputValue(value);
setShowResults(false);
const filteredSuggestions = suggestions.filter(
(suggestion) =>
suggestion.firstname
.toString()
.toLowerCase()
.includes(value.toLowerCase()) ||
suggestion.id.toString().toLowerCase().includes(value.toLowerCase())
);
setFilteredSuggestions(filteredSuggestions);
setDisplaySuggestions(true);
};
const onSelectSuggestion = (index) => {
setSelectedSuggestion(index);
setInputValue(filteredSuggestions[index]);
setFilteredSuggestions([]);
setDisplaySuggestions(false);
};
const SuggestionsList = (props) => {
const {
suggestions,
inputValue,
onSelectSuggestion,
displaySuggestions,
selectedSuggestion,
} = props;
if (inputValue && displaySuggestions) {
if (suggestions.length > 0) {
return (
<ul className="suggestions-list" style={styles.ulstyle}>
{suggestions.map((suggestion, index) => {
const isSelected = selectedSuggestion === index;
const classname = `suggestion ${isSelected ? "selected" : ""}`;
return (
<>
<li
style={styles.listyle}
onClick={finddoctor(suggestion.id)}
key={index}
className={classname}
>
{suggestion.firstname}
</li>
</>
);
})}
</ul>
);
} else {
return <div>No suggestions available...</div>;
}
}
return <></>;
};
useEffect(() => {
axios
.get("admin-panel/all-doctors-list/")
.then((res) => {
const data = res.data;
setShowSerch(data);
});
}, []);
return (
<>
<div className="note-container" style={styles.card}>
<div style={styles.inner}>
<p style={{ textAlign: "left" }}>Search Doctors</p>
<form className="search-form" style={{}}>
{showResults ? (
<FontAwesomeIcon
style={{ marginRight: "-23px" }}
icon={faSearch}
/>
) : null}
<input
onChange={onChange}
value={inputValue}
style={styles.input}
type="Search"
/>
<SuggestionsList
inputValue={inputValue}
selectedSuggestion={selectedSuggestion}
onSelectSuggestion={onSelectSuggestion}
displaySuggestions={displaySuggestions}
suggestions={filteredSuggestions}
/>
</form>
</div>
</div>
</>
);
};
change it do this, and it should work.
<li
style={styles.listyle}
onClick={() => finddoctor(suggestion.id)}
key={index}
>
{suggestion.firstname}
</li>