React transition group is not working. Why? - reactjs

I have a wrapper component that receives data from another component, which is generated in the component even higher up the hierarchy from the global state.
const HubList: FC<IHubList> = ({ items, size, loading, error }) => {
const { history } = useRouter()
if (loading === 'loading') {
return <Spinner />
} else if (loading === 'error') {
return <h5 className="text-center mt-5">{error}</h5>
}
const renderItems = (arr: IListing[]) => {
if (arr.length === 0) {
return (
<CSSTransition timeout={0} classNames="hero">
<h5 className="text-center mt-5">Empty</h5>
</CSSTransition>
)
}
return (
<Box className="space-y-4">
<TransitionGroup component={null}>
{arr.slice(0, size).map((item, idx) => {
return (
<CSSTransition
onEntering={() => console.log('enter')}
timeout={5000}
key={item.id}
classNames="hero"
mountOnEnter
>
<Card challenge={item} action={() => history.push(item.slug)} />
</CSSTransition>
)
})}
</TransitionGroup>
</Box>
)
}
const elements = renderItems(items)
return elements
}
export default HubList
But it doesn't work in any way.

Related

condition return statement Is not working with filter in rendering list of data in react.js

** As you can see i am taking input from the user and display and wanted data display on screen according to the year which you select( filter data according to year) and if there is no item i wanted to display found no expense **
this is my Expenses item code
const ExpenseAll = (props) => {
const [filteredYear, setFilteredYear] = useState("2020");
const filterChangeHandler = (selectedYear) => {
setFilteredYear(selectedYear);
};
const filteredExpenses = props.items.filter((expense) => {
return expense.date.getFullYear().toString() === filteredYear;
});
return (
<div>
<Card className="expenses">
<ExpensesFilter
selected={filteredYear}
onChangeFilter={filterChangeHandler}
/>
<ExpensesList items={filteredExpenses} />
</Card>
</div>
);
};
this is my condition filter code which is not working showing empty screen
if (props.items.length === 0) {
return <h2 className="expenses-list__fallback"> Found no Expense</h2>;
}
return (
<ul className="expenses-list">
{props.items.map((expense) => (
<ExpenseItem
key={expense.id}
title={expense.title}
amount={expense.amount}
date={expense.date}
/>
))}{" "}
;
</ul>
);
}
Try to store filteredExpenses in a state with default value:
const ExpenseAll = (props) => {
const [filteredExpenses, setFilteredExpenses] = useState([]);
const [filteredYear, setFilteredYear] = useState('2020');
const filterChangeHandler = (selectedYear) => {
setFilteredYear(selectedYear);
};
useEffect(() => {
const filtered = props.items.filter((expense) => {
return expense.date.getFullYear().toString() === filteredYear;
});
setFilteredExpenses(filtered)
}, []);
return (
<div>
<Card className='expenses'>
<ExpensesFilter
selected={filteredYear}
onChangeFilter={filterChangeHandler}
/>
<ExpensesList items={filteredExpenses} />
</Card>
</div>
);
};

Setting default state dynamically + onMouseEnter

I have created a scoreboard that updates when a user hovers over each team's card, hovering over a team's card also changes some CSS attributes to make it stand out.
The current default state value is "0", I need the default value to be equal to the top team's score.
Below is the TeamCard component that updates TopGroups with onMouseEnter:
const TeamCard = ({
data,
setDisplayGoals,
setDisplayMilestones,
setDisplayPoints,
}) => {
return (
<TeamCardStyle>
<Row className="d-flex justify-content-between">
{!data && <Spinner />}
{data &&
data.getGroupScores &&
data.getGroupScores.slice(0, 4).map((group, index) => {
return (
<Col
key={guid()}
className="teamCard mt-2 mb-2 mx-1"
onMouseEnter={() => [
setDisplayGoals(group.goalsDone),
setDisplayPoints(group.totalScore),
setDisplayMilestones(group.milestonesDone),
]}
>
<Row>
{/* <div className="arrow-down" /> */}
<p key={guid}>{seed[index]}</p>
</Row>
<Row>
<Col className="hideSmall">
<img className="mouseOn" src="../images/group.png" />
<img
className="mouseOff"
src="../images/groupSelected.png"
/>
</Col>
</Row>
<p key={guid}>{group.name.slice(0, 14)}</p>
</Col>
);
})}
</Row>
</TeamCardStyle>
);
};
This is a snippet of the TopGroups component:
const TopGroups = () => {
const currentQTR = `Q${moment().quarter()} ${moment().year()}`;
const { loading, error, data } = useQuery(GET_GROUP_SCORES, {
variables: { quarter: currentQTR },
});
if (data) {
const sortedGroups = data.getGroupScores.sort((a, b) => {
if (a.totalScore > b.totalScore) {
return -1;
}
if (a.totalScore < b.totalScore) {
return 1;
} else {
return 0;
}
});
const test = data.GoalsDone;
}
if (error) {
return <p>An error has occured</p>;
}
if (loading) {
<Spinner />;
}
const [displayGoals, setDisplayGoals] = useState("0");
const [displayPoints, setDisplayPoints] = useState("0");
const [displayMilestones, setDisplayMilestones] = useState("0");
return (
<div className="row-12">
<TeamCard
data={data}
setDisplayGoals={setDisplayGoals}
setDisplayPoints={setDisplayPoints}
setDisplayMilestones={setDisplayMilestones}
/>
I have included a picture of the app when it first loads, I would like those zeros to be the #1 Team's score, in this case it should represent Team Clown Car.
Maybe you can use something like this when you get the data
useEffect(()=>{
setDisplayGoals("first group's goals"),
setDisplayPoints("first group's points"),
setDisplayMilestones("first group's Milestones")
},[])
you get the idea. Empty brackets will cause useEffect only run on the first render.

serch and redirect to id in react js

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>

not able to redirect in react js using history.push

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
when clicked on li no call going to finddoctor
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>
</>
);
};
Are you using "react-router-dom" in your project?
In this case, you should use the history object in a specific way. For example, you can get it with the useHistory hook.
import { useHistory } from "react-router-dom";
const SuggestionsList = ({
suggestions,
inputValue,
displaySuggestions,
selectedSuggestion,
}) => {
let history = useHistory();
const finddoctor = (e) => {
console.log(e);
history.push(`/detiled/${e} `)
};
if (inputValue && displaySuggestions) {
if (suggestions.length > 0) {
return (
<ul className="suggestions-list">
{suggestions.map((suggestion, index) => {
return (
<li
onClick={() => finddoctor(suggestion.id)}
key={index}
>
{suggestion.firstname}
</li>
)
})}
</ul>
)
} else {
return <div>No suggestions available...</div>
}
}
return <></>
};

React Router 3 Breadcrumb Dropdown

I am trying to change the route based on the dropdown option in the breadcrumb.Any suggestions would be appreciated.
This is the component that is getting the first option but I am not sure how to gran the other options after the dropdown is generated.
const MenuItemViews = ({ params: { category, subCategory, item }, children }) => {
const menuItem = sideNavData.lookupItem(category, subCategory, item);
console.log(menuItem);
console.info(children);
return (
<div>
{
menuItem.name === 'Bill'
? <div>
<h2>Labels</h2>
{
!children
? <Link to={`/${category}/${subCategory}/${item}/${menuItem.childItems[0].name}`} >
<Image src={menuItem.content} />
</Link>
: children
}
</div>
: <ContentContainer>
<h1>{menuItem.name}</h1>
<Image src={menuItem.content} alt='item' />
</ContentContainer>
}
</div>
);
};
this is the component that is displaying the breadcrumbs.
const labelDropdownOptions = [
{ key: 'OptionOne', value: 'OptionOne', text: 'OptionOne' },
{ key: 'OptionTwo', value: 'OptionTwo', text: 'OptionTwo' },
{ key: 'OptionThree', value: 'OptionThree', text: 'OptionThree' },
];
class TopBar extends Component {
resolver = (key) => {
if (key === 'Home') {
return key;
}
return this.props.params[key];
}
dropdownLink = (link, key, text, index, routes) => {
console.log(routes);
if (text === 'OptionOne') {
return (
<Dropdown defaultValue={'OptionOne'} key={key} options={labelDropdownOptions} />
);
}
return <Link key={key} to={link}>{text}</Link>;
}
render() {
const { routes, params } = this.props;
return (
<TopBarHeader>
<IndexLink to='/'>
<HomeIcon><Icon name='home' /></HomeIcon>
</IndexLink>
<BreadcrumbWrapper>
<Breadcrumbs
createLink={this.dropdownLink}
params={params}
resolver={this.resolver}
routes={routes}
/>
</BreadcrumbWrapper>
</TopBarHeader>
);
}
}
I was able to do this by passing this.props.router.push into the onClick prop and specifying the value.
class TopBar extends Component {
resolver = (key) => {
if (key === 'Home') {
return key;
}
return this.props.params[key];
}
dropdownLink = (link, key, text, index, routes) => {
const category = sideNavData.lookupCategory(this.props.category);
if (link === '/TabTwo/Names/Bill/OptionOne' || link === '/TabTwo/Names/Bill/OptionTwo' || link === '/TabTwo/Names/Bill/OptionThree') {
return (
<span key={index}>
{
Object.keys(category).map((subCategory, i) => {
return (
<span key={i}>
{
Object.keys(category[subCategory]).map((item, itemIndex) => (
<span key={itemIndex}>
{
category[subCategory][item].name === 'Bill'
? <Dropdown
defaultValue={'OptionOne'}
options={category[subCategory][item].childItems}
onChange={(event, data) => { this.props.router.push(`/${this.props.category}/${subCategory}/${category[subCategory][item].name}/${data.value}`); }}
/>
: null
}
</span>
))
}
</span>
);
})
}
</span>
);
}
return <Link key={key} to={link}>{text}</Link>;
}
render() {
const { routes, params } = this.props;
return (
<TopBarHeader>
<IndexLink to='/'>
<HomeIcon><Icon name='home' /></HomeIcon>
</IndexLink>
<BreadcrumbWrapper>
<Breadcrumbs
createLink={this.dropdownLink}
params={params}
resolver={this.resolver}
routes={routes}
/>
</BreadcrumbWrapper>
</TopBarHeader>
);
}
}

Resources