Checking the checkBox does not work when DataTable of react-data-table-component has a onSelectedRowsChange callback withs state change

huangapple go评论66阅读模式
英文:

Checking the checkBox does not work when DataTable of react-data-table-component has a onSelectedRowsChange callback withs state change

问题

以下是您要的代码部分的中文翻译:

我有以下的代码,我想要在选中一行时启用编辑按钮。
所以我将editButtonDisabled设置为一个状态变量来处理按钮的禁用属性。

现在的问题是,当我选中未选中的行的复选框时,编辑按钮会被启用,但未选中的复选框仍然保持未选中。如果我再次选中它,然后它就会被选中。当我取消选中它时,按钮会被禁用。

如果我移除回调,它就正常工作。所以我猜测改变变量的状态可能会影响我的复选框。有什么办法可以解决这个问题?

import { useEffect, useState, useRef, useCallback } from 'react';
import { getDocs, query, collection, orderBy, doc } from 'firebase/firestore';
import DataTable from 'react-data-table-component';
import { Button, Checkbox } from '@mui/material';
import { FcInspection } from 'react-icons/fc';
import { IoAdd } from 'react-icons/io5';
import { VscEdit } from 'react-icons/vsc';
import { db } from '../../../services/firebase';
import { Layout } from '../../layout';

export default function InstituteList() {
  const [retrievedFlag, setRetrievedFlag] = useState(false);
  const [institutes, setInstitutes] = useState([]);
  const [editButtonDisabled, setEditButtonDisabled] = useState(true);

  useEffect(() => {
    if (retrievedFlag === false) retrieveData();
  }, []);

  useEffect(() => {
    console.log(editButtonDisabled);
  }, [editButtonDisabled]);

  function retrieveData() {
    try {
      let tmpInstitutes = [];
      const institutesRef = collection(db, 'Institutes');
      const institutesQuery = query(institutesRef, orderBy('title'));
      getDocs(institutesQuery)
      .then(snapshot => {
        snapshot.forEach(doc => {
          let institute = doc.data();
          institute.id = doc.id;
          tmpInstitutes.push(institute);
        });
        setInstitutes(tmpInstitutes);
        setRetrievedFlag(true);
      });
    } catch (error) {
      console.log(error);
    }
  }

  const columns = [
    { name: 'id', selector: row => row.id, omit: true },
    { name: '조직명', selector: row => row.title, sortable: true, grow: 1 },
    { name: '등록일', selector: row => row.date, sortable: true, grow: 1 },
    { name: '주소', selector: row => row.location, sortable: true, grow: 4 },
  ];

  const handleSelectedRowChange = useCallback(state => {
    console.log('设置编辑按钮禁用状态', state);
    setEditButtonDisabled(state.selectedCount === 0);
  });

  const paginationComponentOptions = {
    rowsPerPageText: '페이지당 조회 갯수',
    rangeSeparatorText: '중',
    selectAllRowsItem: true,
    selectAllRowsItemText: '전체',
  };

  const PageHeader = userInfo => {
    const today = new Date();
    return (
      <div className="page-header">
        <div className="page-header__title">
          <FcInspection />
          조직목록조회
        </div>
      </div>
    );
  };

  const DataTableHeader = () => {
    return (
      <div className="page-body__datatable_header">
        <div className="page-body__datatable_header__title">조직목록</div>
        <div className="page-body__datatable_header__title"></div>
      </div>
    );
  };

  const PageDataTable = () => {
    return (
      <div className="page-body__card_datatable">
        <DataTable
          title='조직목록'
          noDataComponent='조회 할 데이터 없습니다.'
          columns={columns}
          data={institutes}
          persistTableHead={true}
          noContextMenu={true}
          selectableRows={true}
          selectableRowsHighlight={true}
          selectableRowsComponent={Checkbox}
          selectableRowsSingle={true}
          onSelectedRowsChange={handleSelectedRowChange}
          pagination
          paginationComponentOptions={paginationComponentOptions}
        />
      </div>
    );
  };

  const PageDataTableButtons = () => {
    console.log("Render PageDataTableButtons");
    return (
      <div className="page-body__card_buttons">
        <Button variant="contained" id="datatable_button_add" startIcon={<IoAdd />}>추가</Button>
        <Button variant="contained" id="datatable_button_modify" startIcon={<VscEdit />} disabled={editButtonDisabled}>수정</Button>
      </div>
    );
  };

  const PageBody = () => {
    return (
      <div className="page-body">
        <div className="page-body__card">
          <PageDataTable />
          <PageDataTableButtons />
        </div>
      </div>
    );
  };

  return (
    <Layout>
      {userInfo => (
        <main className="main">
          <PageHeader />
          <PageBody />
        </main>
      )}
    </Layout>
  );
}
英文:

I have the following code, where I want to enable the edit button when a row is checked.
So I have set editButtonDisabled as a state variable to handle the disable attribute of the button.

Now the problem is when I check the unchecked checkBox of the row, the edit button gets enabled, but the uncheck checkbox remains unchecked. If I check it again, then it becomes checked. When I uncheck it, it becomes unchecked with the button being disabled.

If I remove the callback, it works fine. So I am guessing that the changing the state of the variable is messing with my checkbox. What can be done to resolve this problem?

import { useEffect, useState, useRef, useCallback } from &#39;react&#39;;
import { getDocs, query, collection, orderBy, doc } from &#39;firebase/firestore&#39;;
import DataTable from &#39;react-data-table-component&#39;;
import { Button, Checkbox } from &#39;@mui/material&#39;;
import { FcInspection } from &#39;react-icons/fc&#39;;
import { IoAdd } from &#39;react-icons/io5&#39;;
import { VscEdit } from &#39;react-icons/vsc&#39;;
import { db } from &#39;../../../services/firebase&#39;;
import { Layout } from &#39;../../layout&#39;;
export default function InstituteList() {
const [retrievedFlag, setRetrievedFlag] = useState(false);
const [institutes, setInstitutes] = useState([]);
const [editButtonDisabled, setEditButtonDisabled] = useState(true);
useEffect(() =&gt; {
if (retrievedFlag === false) retrieveData();
}, [])
useEffect(() =&gt; {
console.log(editButtonDisabled);
}, [editButtonDisabled])
function retrieveData() {
try {
let tmpInstitutes = [];
const institutesRef = collection(db, &#39;Institutes&#39;);
const institutesQuery = query(institutesRef, orderBy(&#39;title&#39;));
getDocs(institutesQuery)
.then(snapshot =&gt; {
snapshot.forEach((doc) =&gt; {
let institute = doc.data();
institute.id = doc.id;
tmpInstitutes.push(institute);
});
setInstitutes(tmpInstitutes);
setRetrievedFlag(true);
});
} catch (error) {
console.log(error);
}
}
const columns = [
{ name: &#39;id&#39;, selector: row =&gt; row.id, omit: true },
{ name: &#39;조직명&#39;, selector: row =&gt; row.title, sortable: true, grow: 1 },
{ name: &#39;등록일&#39;, selector: row =&gt; row.date, sortable: true, grow: 1 },
{ name: &#39;주소&#39;, selector: row =&gt; row.location, sortable: true, grow: 4 },
];
const handleSelectedRowChange = useCallback((state) =&gt; {
console.log(&#39;Set edit button disable state&#39;, state);
setEditButtonDisabled(state.selectedCount == 0);
});
const paginationComponentOptions = {
rowsPerPageText: &#39;페이지당 조회 갯수&#39;,
rangeSeparatorText: &#39;중&#39;,
selectAllRowsItem: true,
selectAllRowsItemText: &#39;전체&#39;,
}
const PageHeader = (userInfo) =&gt; {
const today = new Date();
return (
&lt;div className=&quot;page-header&quot;&gt;
&lt;div className=&quot;page-header__title&quot;&gt;
&lt;FcInspection /&gt;
조직목록조회
&lt;/div&gt;
&lt;/div&gt;
)
}
const DataTableHeader = () =&gt; {
return (
&lt;div className=&quot;page-body__datatable_header&quot;&gt;
&lt;div className=&quot;page-body__datatable_header__title&quot;&gt;조직목록&lt;/div&gt;
&lt;div className=&quot;page-body__datatable_header__title&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
);
}
const PageDataTable = () =&gt; {
return (
&lt;div className=&quot;page-body__card_datatable&quot;&gt;
&lt;DataTable
title=&#39;조직목록&#39;
noDataComponent=&#39;조회 할 데이터 없습니다.&#39;
columns={columns}
data={institutes}
persistTableHead={true}
noContextMenu={true}
selectableRows={true}
selectableRowsHighlight={true}
selectableRowsComponent={Checkbox}
selectableRowsSingle={true}
onSelectedRowsChange={handleSelectedRowChange}
pagination
paginationComponentOptions={paginationComponentOptions}
/&gt;
&lt;/div&gt;
);
}
const PageDataTableButtons = () =&gt; {
console.log(&quot;Render PageDataTableButtons&quot;);
return (
&lt;div className=&quot;page-body__card_buttons&quot;&gt;
&lt;Button variant=&quot;contained&quot; id=&quot;datatable_button_add&quot; startIcon={&lt;IoAdd /&gt;}&gt;추가&lt;/Button&gt;
&lt;Button variant=&quot;contained&quot; id=&quot;datatable_button_modify&quot; startIcon={&lt;VscEdit /&gt;} disabled={editButtonDisabled}&gt;수정&lt;/Button&gt;
&lt;/div&gt;
)
}
const PageBody = () =&gt; {
return (
&lt;div className=&quot;page-body&quot;&gt;
&lt;div className=&quot;page-body__card&quot;&gt;
&lt;PageDataTable /&gt;
&lt;PageDataTableButtons /&gt;
&lt;/div&gt;
&lt;/div&gt;
);
}
return (
&lt;Layout&gt;
{userInfo =&gt; (
&lt;main className=&quot;main&quot;&gt;
&lt;PageHeader /&gt;
&lt;PageBody /&gt;
&lt;/main&gt;
)}
&lt;/Layout&gt;
);
}

答案1

得分: 0

看起来是 useEffect 导致了问题。

我已经为 datatable 相关的组件创建了一个单独的组件文件,问题得到了解决。

但我仍然想知道为什么它导致了问题。

英文:

It seems that useEffect is causing the problem.

I have created a separate component file for datatable related components, and the problem was resolved.

But I would still love to know why it was causing the problem.

huangapple
  • 本文由 发表于 2023年3月8日 15:28:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75670313.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定