react 中的事件处理问题

问题描述 投票:0回答:1
import AppSelect from '@/components/form-fields/AppSelect';
import {
  Box,
  Button,
  CircularProgress,
  Divider,
  List,
  ListItemButton,
  ListItemIcon,
  ListItemText,
  Stack,
  Typography,
  useTheme,
} from '@mui/material';
import React, { useEffect } from 'react';
import { BlobProvider, PDFDownloadLink } from '@react-pdf/renderer';
import Iconify from '@/components/iconify';
import PaySlipPDF from './paySlipPDF';
import useGet from '@/hooks/useGet';
import { useForm } from 'react-hook-form';
import { useParams } from 'react-router-dom';
import { PAYSTRUCTURE_PAYROLL_LIST_ENDPOINT } from '@/constants/my-company/employee-directory';
import useUserStore from '@/store/user.store';

type PayRoll = {
  year: string;
  month: string;
  monthText: string;
  payrollId: string;
};

const Payslips = () => {
  const theme = useTheme();
  const [selectedIndex, setSelectedIndex] = React.useState(1);
  const [payrollId, setPayrollId] = React.useState('');
  const [list, setlist] = React.useState<PayRoll[] | undefined>([]);
  const { control, watch } = useForm();
  const user = useUserStore((state) => state.user);
  // const {id} = useParams();
  const { data } = useGet<any>(
    PAYSTRUCTURE_PAYROLL_LIST_ENDPOINT (user?.Employee?.id), ['getPayrunListForEmp']
  );

  
  // const options = [...new Set(data?.map((each: { year: any; }) => each.year))].map((each) => ({
  //   label: each,
  //   value: each,
  // }));


  // const year = watch('year');
  // useEffect(() => {
  //   if (data) {
  //     setlist(data?.filter((each: { year: any; }) => each.year === year));
  //   }
  // }, [year, data]);
  
  const options = [...new Set(data?.map((each:any) => each.year))].map((each) => ({
    label: each,
    value: each,
  }));

  const year = watch('year');
  useEffect(() => {
    setlist(data?.filter((each:any) => each.year == year));
  }, [year, data, payrollId]);
  const handleListItemClick = (index: number, id: string) => {
    console.log('Clicked index:', index);
    console.log('Clicked payrollId:', id);
    setSelectedIndex(index);
    setPayrollId(id);
  };
  
  
  // Add your custom styles for the header box
  const headerStyles = {
    display: 'flex',
    flexDirection: 'row',
    width: '70%',
    justifyContent: 'space-between',
    alignItems: 'center',
    padding: theme.spacing(2),
    backgroundColor: '#4A5363',
    color: theme.palette.primary.contrastText,
  };
  // console.log('Data:', data);
  // console.log('Options:', options);
  // console.log('List:', list);
  // console.log('Mapped Years:', data?.map((each: { year: any; }) => each.year));
  return (
    <Stack
      sx={{
        display: 'flex',
        flexDirection: 'row',
        margin: 2,
        gap: 2,
        flexWrap: 'wrap',
        height: '100%',

        [theme.breakpoints.down('sm')]: {
          flexDirection: 'column',
        },
      }}
    >
      <Stack
        direction='column'
        sx={{
          width: '250px',
          [theme.breakpoints.down('sm')]: {
            width: '100%',
          },
        }}
        gap={2}
      >
        <AppSelect control={control} name='year' options={options} />
        <Box component='span' sx={{ bgcolor: 'background.paper', flex: 1 }}>
          <List component='nav' aria-label='main mailbox folders'>
            {list?.map((each, idx) => (
              <ListItemButton
                selected={selectedIndex === idx}
                onClick={(event) => handleListItemClick(idx, each.payrollId)}
              >
                <ListItemText primary={each.monthText} />
              </ListItemButton>
            ))}
          </List>
        </Box>
      </Stack>
      <Box sx={{ flex: 1 }}>
        {payrollId ? (
          <PaySlipPDF id={payrollId} />
        ) : (
          <Typography variant='body2'>Select Year and Month </Typography>
        )}
      </Box>
    </Stack>
  );
};

export default Payslips;

从这段代码中有一个组件AppSelect,它是一个可重用的组件,它有一个选项,这个选项是一个从api获取值的值,它映射到数组值中,如果我选择这个选项,它会显示像2024,2025这样的年份是从 api 获取的,如果我选择一年中的一个,它将在列表中显示一月、二月和三月等月份,并在 listitembutton 中显示它一切正常,但每当我单击第一个月(如 jan)时,它都会从 api 获取数据并显示工资单第一次加载页面时同一页面中的 pdf 文件,在我选择 2 月后,它不会获取整个月的数据,当我在第一次加载页面时单击它时,我需要获取整个月的数据,请给我解决方案

 const handleListItemClick = (index: number, id: string) => {
    setSelectedIndex(index);
    if (payrollId !== id) {
      setPayrollId(id);
    } else {
      // Reset payrollId if the same month is selected again
      setPayrollId('');
    }
  };

我尝试了这个逻辑,但在这个逻辑中,当我每月点击三次后,工资单ID会被重置,然后只有它获取数据,所以我不需要这种行为

javascript reactjs event-handling
1个回答
0
投票

const handleListItemClick = (index: number, id: string) => {
  setSelectedIndex(index);
  if (payrollId !== id) {
    // If a different month is clicked, reset payrollId and set it again to trigger data fetching
    setPayrollId('');
    setTimeout(() => {
      setPayrollId(id);
    }, 0); // Ensuring the id is set after resetting to trigger the effect
    console.log("Reset payrollId");
  } else {
    // Reset payrollId if the same month is selected again
    setPayrollId('');
    console.log("Reset payrollId");
    // Reset the data since the same month is selected again
    setlist([]);
  }
};

在本次调整中,当点击不同月份时,payrollId 首先会被重置,然后在短暂延迟后再次设置为点击的 id。这可确保触发效果以获取所选月份的数据。如果再次点击同月,payrollId 会随着数据一起重置。

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