当搜索或过滤值发生变化时,如何在 material-ui 的数据网格中选择我的行

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

我正在使用材料 ui 数据网格来显示文章列表。用户可以选择一行或多行/文章。

我实现了自己的过滤器和搜索栏。

当用户选择行然后过滤或搜索时,他将丢失选择的前一行。

如何避免这种情况并保持选中该行?

我认为问题是当用户选择初始行中的文章然后过滤行时,它会减少行并且不在过滤行中的所选文章将只是取消选择

这是我的父组件,其中我有初始行/文章列表,以及搜索、筛选和选择组件

import * as React from 'react';
import { Paper } from '@mui/material';

import { FilterArticle } from './FilterArticle';
import { SearchArticle } from './SearchArticle';
import { useDispatch } from 'react-redux';
import { setActualTitle } from 'feature/title.slice';
import { SelectionArticle } from './SelectionArticle';

export const SelectArticle = ({ control, watch, register, setValue }) => {
 const list = [
    {
      id: 1,
      name: 'Snow',
      age: 35,
      stack: '3',
      service: '1',
      asset: '1',
      price: [{ SSL: 5 }, { SSB: 10 }, { SSF: 15 }],
      quantity: 5,
    },
    {
      id: 2,
      name: 'Lannister',
      age: 42,
      stack: '3',
      service: '1',
      asset: '2',
      price: [{ SSL: 5 }, { SSB: 10 }, { SSF: 15 }],
      quantity: 5,
    },
    {
      id: 3,
      name: 'Lannister',
      age: 45,
      stack: '3',
      service: '1',
      asset: '3',
      price: [{ SSL: 5 }, { SSB: 10 }, { SSF: 15 }],
      quantity: 5,
    },
  ];

  const dispatch = useDispatch();
  
  
  const [rows, setRows] = React.useState(list);

  React.useEffect(() => {
    dispatch(setActualTitle('Articles professional services'));
   }, []);

  return (
    <div className="form">
      <label className="subtitle">Select Articles</label>{' '}
        <Paper className="form_group" style={{ height: 550, width: '60vw' }}>
          <FilterArticle
            setRows={setRows}
            watch={watch}
            list={list}
            register={register}
          />
          <SearchArticle setRows={setRows} list={list} />

          <SelectionArticle
            list={list}
            setValue={setValue}
            control={control}
            rows={rows}
            watch={watch}
          />
        </Paper>
      
    </div>
  );
};

这是我的 searchArticle 组件,我把搜索文章的逻辑放在这里

import { Box, TextField } from '@mui/material';
import { RxCross2 } from 'react-icons/rx';
import React from 'react';

export const SearchArticle = ({ setRows, list }) => {
  const [search, setSearch] = React.useState('');

  const requestSearch = (search) => {
    if (search === '') {
      setRows(list);
      return;
    }
    const filteredRows = list?.filter((row) => {
      return (
        row.name?.toLowerCase().includes(search?.toLowerCase()) ||
        row.service?.toLowerCase().includes(search?.toLowerCase()) ||
        row.asset?.toLowerCase().includes(search?.toLowerCase()) ||
        (row.stack && row.stack.toString().includes(search))
      );
    });
    setRows(filteredRows);
  };

  React.useEffect(() => {
    requestSearch(search);
  }, [search]);

  const cancelSearch = () => {
    setSearch('');
  };

  return (
    <Box sx={{ m: 1, minWidth: 120, display: 'flex', alignItems: 'center' }}>
      <TextField
        id="standard-basic"
        label="search..."
        variant="standard"
        className="searchBar_input"
        placeholder="search..."
        value={search}
        onChange={(e) => setSearch(e.target.value)}
      />
      <RxCross2 onClick={cancelSearch} />
    </Box>
  );
};

这里是带有数据网格的 SelectionArticle 组件

import { DataGrid } from '@mui/x-data-grid';
import React, { useEffect, useState } from 'react';
import { Stack } from 'react-bootstrap';
import { useFieldArray } from 'react-hook-form';

export const SelectionArticle = ({ control, setValue, rows, watch }) => {
  const entityConcerned = watch('OffersInfos.entityConcerned');
  const articleSelected = watch('Articles');
  const [selectedRows, setSelectedRows] = useState(articleSelected);

  const [selectionModel, setSelectionModel] = useState(() =>
    rows.filter((r) => r.id > 2).map((r) => r.id)
  );

  useEffect(() => {
    replace(selectedRows);
  }, [selectedRows]);

  const columns = [
    { field: 'id', headerName: 'ID', width: 70 },
    { field: 'name', headerName: 'name', width: 130 },
    {
      field: 'age',
      headerName: 'Age',
      type: 'number',
      width: 90,
    },
    {
      field: 'stack',
      headerName: 'Stacks',
      width: 90,
    },
    {
      field: 'service',
      headerName: 'service',
      width: 90,
    },
    {
      field: 'asset',
      headerName: 'asset',
      width: 90,
    },
    {
      field: 'quantity',
      headerName: 'quantity',
      width: 90,
    },
    {
      field: 'price',
      headerName: 'price',
      width: 90,
      renderCell: (params) => {
        const priceObj = params.row.price.find((obj) => obj[entityConcerned]);
        const price = priceObj ? priceObj[entityConcerned] : '';

        return <span>{price}</span>;
      },
    },
  ];

  const onRowsSelectionHandler = (ids) => {
    const selectedRowsData = ids.map((id) => rows.find((row) => row.id === id));
    setSelectedRows(selectedRowsData);
  };

  const { replace } = useFieldArray({
    control,
    name: 'Articles',
  });

  function NoRowsOverlay() {
    return (
      <Stack height="100%" alignItems="center" justifyContent="center">
        Aucun article
      </Stack>
    );
  }
  function NoResultsOverlay() {
    return (
      <Stack height="100%" alignItems="center" justifyContent="center">
        Aucun résultat
      </Stack>
    );
  }

  useEffect(() => {
    // Update the selection model based on the selected articles
    const selectedArticleIds = articleSelected?.map((article) => article?.id);
    const selectedRowsIds = rows
      .filter((row) => selectedArticleIds?.includes(row?.id))
      .map((row) => row?.id);
    setSelectionModel(selectedRowsIds);
  }, [articleSelected]);

  return (
    <DataGrid
      rows={rows}
      getRowId={(row) => row?.id}
      columns={columns}
      checkboxSelection
      components={{ NoRowsOverlay, NoResultsOverlay }}
      componentsProps={{
        pagination: {
          labelRowsPerPage: 'Articles/page',
          rowsPerPageOptions: [5, 10, 20, 50, 100],
        },
      }}
      onSelectionModelChange={(ids) => {
        onRowsSelectionHandler(ids);
      }}
      selectionModel={selectionModel}  
    />
  );
};

我试着按照这个https://github.com/mui/mui-x/issues/2842但我真的需要保留自己的过滤器和搜索栏。

我正在尝试更新 SelectionArticle 中的 useEffect 以保持选中行,即使行正在更改但没有成功。

reactjs material-ui datagrid react-hook-form
© www.soinside.com 2019 - 2024. All rights reserved.