我有一个 React 应用程序,其中使用 Material-UI 的自动完成组件来根据所选品牌过滤卡片。这些卡片代表不同的汽车型号,当用户从“自动完成”下拉列表中选择一个品牌时,我想过滤它们。
import * as React from 'react';
import TextField from '@mui/material/TextField';
import Autocomplete from '@mui/material/Autocomplete';
const top100Cars = [
{ label: 'Toyota' },
{ label: 'Ford' },
{ label: 'Chevrolet' },
{ label: 'Tesla' },
{ label: 'Honda' },
{ label: 'BMW' },
{ label: 'Audi' },
{ label: 'Mercedes-Benz' },
{ label: 'Ferrari' },
{ label: 'Porsche' },
{ label: 'Lamborghini' },
{ label: 'Nissan' },
{ label: 'Volkswagen' },
{ label: 'Mazda' },
{ label: 'DeLorean' },
{ label: 'Dodge' },
];
export default function searchBar() {
const [selectedBrand, setSelectedBrand] = React.useState(null);
return (
<Autocomplete
disablePortal
id="combo-box-demo"
options={top100Cars}
value={selectedBrand}
onChange={(event, newValue) => {
setSelectedBrand(newValue);
}}
sx={{
width: 254, backgroundColor: 'white', borderRadius: 50,
}}
renderInput={(params) => (
<TextField
{...params}
label="Марка"
size='small'
/>
)}
/>
);
}
import * as React from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { styled } from '@mui/material/styles';
import Card from '@mui/material/Card';
import CardHeader from '@mui/material/CardHeader';
import CardMedia from '@mui/material/CardMedia';
import Checkbox from '@mui/material/Checkbox';
import FormControlLabel from '@mui/material/FormControlLabel';
import FormGroup from '@mui/material/FormGroup';
import IconButton, { IconButtonProps } from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import Rating from '@mui/material/Rating';
import Grid from '@mui/material/Grid';
import Button from '@mui/material/Button';
import LocationOnIcon from './SVGiCON';
type ExpandMoreProps = IconButtonProps & {
expand: boolean;
};
const ExpandMore = styled((props: ExpandMoreProps) => {
const { expand, ...other } = props;
const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
return <IconButton {...other} />;
})(({ theme, expand }) => ({
transform: !expand ? 'rotate(0deg)' : 'rotate(180deg)',
marginLeft: 'auto',
transition: theme.transitions.create('transform', {
duration: theme.transitions.duration.shortest,
}),
}));
type RecipeReviewCardProps = {
to: string; // Specify the destination when the button is clicked
// Add any additional props you may need
};
export const RecipeReviewCard: React.FC<RecipeReviewCardProps> = ({ to }) => {
const [expanded, setExpanded] = React.useState(false);
const navigate = useNavigate();
const handleExpandClick = () => {
setExpanded(!expanded);
};
const [state, setState] = React.useState({
gilad: false,
jason: false,
antoine: false,
});
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setState({
...state,
[event.target.name]: event.target.checked,
});
};
const { gilad, jason, antoine } = state;
const [value, setValue] = React.useState<number | null>(2);
const handleButtonClick = () => {
navigate(to);
};
return (
<Card style={{
width: '312px', height: '285px', backgroundColor: "gray",
}}>
<CardHeader
title="Ауди, А4"
subheader="София, София-град"
// titleTypographyProps={{
// fontSize: 22,
// }}
subheaderTypographyProps={{
color: "white",
}}
style={{
textAlign: 'center', fontSize: '1px', marginBottom: '-10px', marginTop: '-9px', color: "white",
}}
/>
<Grid container>
<Grid item xs={6}>
{/* Adjust the width and height of the image as needed */}
<CardMedia
component="img"
height="84.28px"
image="https://images.pexels.com/photos/244212/pexels-photo-244212.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
style={{ marginLeft: '10px' }}
/>
</Grid>
<Grid item
xs={6}
sx={{
width: '43px', top: '6px', left: '245px', height: '17px', // Set the width to 100% or adjust as needed
}}>
<Typography style={{
display: 'flex', alignItems: 'center', marginLeft: '20px', fontSize: '14px', color: "white",
}}>
<LocationOnIcon style={{ marginRight: '10px', width: '15px', height: '15px' }} />
Дизел
</Typography>
<Typography style={{
display: 'flex', alignItems: 'center', marginLeft: '20px', fontSize: '14px', color: "white",
}}>
<LocationOnIcon style={{ marginRight: '10px', width: '15px', height: '15px' }} />
Бял
</Typography>
<Typography style={{
display: 'flex', alignItems: 'center', marginLeft: '20px', fontSize: '14px', color: "white",
}}>
<LocationOnIcon style={{ marginRight: '10px', width: '15px', height: '15px' }} />
2013 г.
</Typography>
<Typography style={{
display: 'flex', alignItems: 'center', marginLeft: '20px', fontSize: '14px', color: "white",
}}>
<LocationOnIcon style={{
marginRight: '10px', width: '15px', height: '15px', color: "white",
}} />
290 000 км
</Typography>
</Grid>
</Grid>
<FormGroup style={{ marginLeft: '10px', marginTop: '11px' }}>
<FormControlLabel
style={{ marginBottom: '-10px', color: "white" }}
control={
<Checkbox
checked={gilad}
onChange={handleChange}
name="gilad"
size='small'
style={{ color: 'white' }} />
}
label="Реален пробег"
/>
<FormControlLabel
style={{ color: "white" }}
control={
<Checkbox checked={jason}
onChange={handleChange}
name="jason"
size='small'
style={{ color: 'white' }} />
}
label="Първи собственик"
/>
</FormGroup>
<Typography
component="legend"
style={{ marginLeft: "8px", fontSize: '13px', color: "white" }}
>Рейтинг
</Typography>
<Grid container>
<Grid item xs={12} style={{ marginLeft: '8px', display: 'flex', alignItems: 'center' }}>
<Rating name="read-only" value={value} readOnly size="small" />
<Link to={to}>
<Button
variant="contained"
color="success"
style={{
marginLeft: '88px',
width: '103px',
height: '24px',
fontSize: '10px',
borderRadius: '50px',
}}
onClick={handleButtonClick}
>
Виж повече
</Button>
</Link>
</Grid>
</Grid>
</Card>
);
};
import * as React from 'react';
import Grid from '@mui/material/Grid';
import { RecipeReviewCard } from './CardTemplate';
export default function ResponsiveCardContainer() {
return (
<Grid container justifyContent="center" spacing={5} marginTop={10} paddingBottom={5}>
<Grid item>
<RecipeReviewCard to="/more-info/:id" />
</Grid>
<Grid item>
<RecipeReviewCard to="/more-info/:id" />
</Grid>
<Grid item>
<RecipeReviewCard to="/more-info/:id" />
</Grid>
<Grid item>
<RecipeReviewCard to="/more-info/:id" />
</Grid>
</Grid>
);
}
const DefaultComponent: React.FC = () => {
return (
<>
{sections.map(({ component, sectionId }) => (
<SectionContainer key={sectionId} sectionId={sectionId}>
{component}
</SectionContainer>
))}
<MultiSearchBar />
<ResponsiveCardContainer />
</>
);
};
现在看起来像这样:
[![Here is how it looks right now][1]][1]
但是,过滤并没有按预期工作。当我选择一个品牌时,卡片不会相应更新。这是因为我不知道如何实现这个逻辑。
我知道也许我现有的实现并不完美,将不胜感激任何建议。
这是一项紧急任务,如果有人帮助我,我会非常高兴!
有人可以帮助我吗?
我在工作中几乎必须做同样的事情,首先在你的汽车模型中,你必须有办法知道哪个汽车模型属于哪个汽车品牌,比如 id ? 之后,使用 useEffect 钩子,当您选择的品牌状态发生变化时,该钩子会重新渲染,并在其中过滤您循环显示的汽车模型的状态以显示汽车卡片。请记住,您必须有一个单独的状态来保存所有汽车模型,并有一个状态来保持过滤,您将渲染过滤后的状态。这是下面的代码示例
const [carModels,setCarModels] = React.useState();
const [filteredCarModels,setFilteredCarModels] = React.useState();
useEffect(() => {
const filteredData = carModels.where(x => x.carBrandId == selectedBrand.id);
setFilteredCarModels(filteredData);
},[selectedBrand])
我希望它对您有所帮助,或者至少能给您一些见解!