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>
</>
) : (
""
)}
Related
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>
);
};
am making a slider, when i click on an item to slide to the second item, the screen flashs when the function is called ( the func that changes the items )
This comes exactly when clickAction(); is called.
Here is the demo : https://gfycat.com/ultimatetiredequestrian
PS: the click is handled in another file, here is some code :
const VerticalCarousel = ({ clickActionTransfer }) => {
.
..
...
<button
data-glitch={item.type}
type="button"
onClick={clickActionTransfer}
key={i}>
CLICK
{item.type}
</button>
};
This is my <SLider/> :
import React, { useState, useEffect } from "react";
import VerticalCarousel from "./carousel/VerticalCarousel";
const Slider = ({ getData, idd, clickAction, children }) => {
const [dataSlider, setDataSlider] = useState([]);
const [displayTitleState, setDisplayTitleState] = useState(true);
const [displayCarouselState, setDisplayCarouselState] = useState(true);
const [currentIndex, setCurrentIndex] = useState(0);
const [length, setLength] = useState(children.length);
const handleSlideClick = () => {
if (currentIndex < length - 1) {
setCurrentIndex((prevState) => prevState + 1);
}
setDisplayCarouselState(false);
setTimeout(() => {
setDisplayTitleState(false);
clickAction();
}, 1000);
setTimeout(() => {
setDisplayTitleState(true);
setDisplayCarouselState(true);
}, 2600);
};
useEffect(() => {
setLength(children.length);
setDataSlider(getData);
}, [getData, children]);
return (
<div className="slider__container">
{dataSlider.map((i) => {
return (
idd === i.id && (
<div key={i.id}>
<div
style={{
transform: `translateX(-${currentIndex * 100}%)`,
display: "flex",
transition: "all .5s linear",
}}
>
{" "}
{children}{" "}
</div>
<div className="slider__content">
<div
className={
"slider__left " + (i.theme === "light" ? "light-theme" : "")
}
>
<div className="slider__progressBar">
{" "}
{i.progressBar.nb1}{" "}
<span className="slider__progressBar-lightTxt">
{" "}
{i.progressBar.nb1}
</span>{" "}
{i.progressBar.text}
</div>
<h1 className={displayTitleState ? "showTitle" : "hideTitle"}>
{" "}
{i.title}{" "}
</h1>
</div>
<div
className={`slider__right ${
displayCarouselState ? "showCarousel" : "hideCarousel"
} ${i.theme === "light" ? "light-theme" : ""}`}
>
<VerticalCarousel
data={i.slider}
clickActionTransfer={handleSlideClick}
/>
</div>
</div>
</div>
)
);
})}
</div>
);
};
export default Slider;
App.js :
import React, { useState, useEffect } from "react";
import Slider from "./Slider";
import "./App.scss";
function App() {
const [loadSlide, setLoadSlide] = useState(0);
const [data, setData] = useState([]);
const handleclick = () => {
setLoadSlide(loadSlide + 1);
};
useEffect(() => {
setLoadSlide((loadSlide) => loadSlide + 1);
fetch("/data.json")
.then((response) => response.json())
.then((json) => {
setData(json.lvmh.sliders);
});
}, []);
return (
<div className="App">
<div
className={
"slider " +
(loadSlide >= 1 &&
loadSlide <= data.length &&
loadSlide + 1 &&
`ifSlider`)
}
>
<>
{loadSlide >= 0 && loadSlide <= data.length && loadSlide + 1 && (
<Slider clickAction={handleclick} idd={loadSlide} getData={data}>
{data.map((img) => {
return (
<img className={"slider__bg---- "} src={img.img} alt="" />
);
})}
</Slider>
)}
</>
</div>
</div>
);
}
export default App;
I found it, i don't know why but the bug comes from the browser console when it's opened ! weird !
I am making a calculator using react.
Every time I press a number button, the whole application re-renders, instead of the <Display />.
To prevent it, I tried 2 different approaches for App, But neither of them worked.
Here is the sandbox link.
Any help would be appreciated.
Put clickHandler inside of useCallback()
const App = () => {
const [screen, setScreen] = useState("0");
console.log("render");
const clickHandler = useCallback(
(val) => {
if (val === "AC") {
setScreen("");
return;
}
screen === "0" ? setScreen(val) : setScreen(screen + val);
},
[screen]
);
return (
<div className="App">
<div className="display">{screen}</div>
<ButtonList clickHandler={clickHandler} />
</div>
);
};
Put Display component inside of React.memo
const App = () => {
const [screen, setScreen] = useState("0");
console.log("render");
const clickHandler = (val) => {
if (val === "AC") {
setScreen("");
return;
}
screen === "0" ? setScreen(val) : setScreen(screen + val);
};
const displayComponent = () => {
return (
<>
<div className="display">{screen}</div>
<ButtonList clickHandler={clickHandler} />
</>
);
};
const MemoizedComponent = React.memo(displayComponent);
return (
<div className="App">
<MemoizedComponent />
</div>
);
};
And here's the ButtonList & Button component.
export const ButtonList = ({ clickHandler }) => {
const arr = [...Array.from(Array(10).keys()).reverse(), "AC"];
return (
<div className="buttons">
<div className="numbersWrapper">
{arr.map((item) => (
<Button
key={item}
clickHandler={clickHandler}
value={item.toString()}
/>
))}
</div>
</div>
);
};
export const Button = ({ value, clickHandler }) => {
return (
<button
name={value}
onClick={() => {
clickHandler(value); //where the clickEvent happens
}}
>
{value}
</button>
);
};
If you don't want a component re-render,You would have to define the click handler in another component that you would like to re-render.
So do it like this:
const App = () => {
console.log("render");
return (
<div className="App">
<childComponent />
</div>
);
};
export const childComponent = () => {
const [screen, setScreen] = useState("0");
const clickHandler = (val) => {
if (val === "AC") {
setScreen("");
return;
}
screen === "0" ? setScreen(val) : setScreen(screen + val);
};
return (
<>
<div className="display">{screen}</div>
<ButtonList clickHandler={clickHandler} />
</>
);
}
This way you prevent a particular component from re-rendering. But note that if you update a state or do anything from which causes re-renders from the parent component, It would equally re-render the child component.
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>