React - 根据自动完成中选择的值过滤卡片

问题描述 投票:0回答:1

我有一个 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>
  );
}

下面是 main.tsx 中的代码

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]

但是,过滤并没有按预期工作。当我选择一个品牌时,卡片不会相应更新。这是因为我不知道如何实现这个逻辑。

我知道也许我现有的实现并不完美,将不胜感激任何建议。

这是一项紧急任务,如果有人帮助我,我会非常高兴!

有人可以帮助我吗?

javascript reactjs react-native material-ui filtering
1个回答
0
投票

我在工作中几乎必须做同样的事情,首先在你的汽车模型中,你必须有办法知道哪个汽车模型属于哪个汽车品牌,比如 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])

我希望它对您有所帮助,或者至少能给您一些见解!

© www.soinside.com 2019 - 2024. All rights reserved.