在状态更改 * 和 * 按钮点击时调用函数

问题描述

我需要根据 4 个输入生成一个表格。需要填写输入,然后必须单击一个按钮才能生成表格。此外,如果页面更改,该表应重新生成。所以基本上,我需要该功能在按下按钮或页面更改时运行。

因为分页,我已经实现了 useEffect/useCallback。然而,问题在于 useCallback。因为 4 个输入作为依赖项传递给 useCallback,所以在我单击按钮之前会生成表,我不希望这种情况发生。我无法删除作为依赖项的输入。

我可以添加一个状态,在按下按钮后更改状态并将该状态添加为 useEffect 中的依赖项,以便每次按下按钮时,状态都会更改,因此 useEffect 被调用 -> 表被重新渲染。我想到了这一点,但我不确定是否要在混合中添加一个状态,因为它看起来很浪费。

4 个输入作为 props 从父组件传递过来。

我该怎么做:

  1. 在我点击按钮之前阻止 generateTable 执行
  2. 点击按钮后执行 generateTable

代码

const Table: FC<Table> = ({ values }) => {
  const [page,setPage] = useState(1);

  const [getData,getDataResponse] = useLazyQuery<
    IQueryResponse,IQueryInput
  >(QUERY_NAME),{
    fetchPolicy: 'no-cache',onError: error => {},});

  const handleButtonOnClick = () => {
    generateTable();
  };

  const handlePageChange = (_event: unkNown,value: number) => {
    setPage(value);
  };

  const generateTable = useCallback(() => {
    if (
      values?.input1 &&
      values?.input2 &&
      values?.input3 &&
      values?.input4 
    ) {
      getData({
        variables: {
          input1 : values.input1,input2 : values.input2,input3 : values.input3,input4 : values.input4,limit: rowsPerPage,offset: rowsPerPage * (page - 1),},});
    }

  },[getData,page,values]);

  useEffect(() => {
    generateTable();
  },[generateTable,page]);

  .
  .
  .
  
  return (
    <Button onClick={handleOnclick}>Generate table</Button>

    {getDataResponse.data ? (
      <Table> ... </Table>
      <Pagination page={page} onChange={handlePageChange} />
    ) : ''}
  )

解决方法

我设法通过简化代码并完全摆脱 useEffect 和 useCallback 钩子并只传递之前需要 useEffect 的值来解决这个问题。

const Table: FC<Table> = ({ values }) => {
  const [page,setPage] = useState(1);

  const [getData,getDataResponse] = useLazyQuery<
    IQueryResponse,IQueryInput
  >(QUERY_NAME),{
    fetchPolicy: 'no-cache',onError: error => {},});

  const handleButtonOnClick = () => {
    generateTable(page);
  };

  const handlePageChange = (_event: unknown,value: number) => {
    setPage(value);
    generateTable(value)
  };

  const generateTable = (page: number) => {
    if (
      values?.input1 &&
      values?.input2 &&
      values?.input3 &&
      values?.input4 
    ) {
      getData({
        variables: {
          input1 : values.input1,input2 : values.input2,input3 : values.input3,input4 : values.input4,limit: rowsPerPage,offset: rowsPerPage * (page - 1),},});
    }
  }

  .
  .
  .
  
  return (
    <Button onClick={handleOnclick}>Generate table</Button>

    {getDataResponse.data ? (
      <Table> ... </Table>
      <Pagination page={page} onChange={handlePageChange} />
    ) : ''}
  )