【问题标题】:Call a function on state change *and* on button click在状态更改*和*按钮单击时调用函数
【发布时间】:2021-07-27 15:39:08
【问题描述】:

我有一个需要根据 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} />
    ) : ''}
  )

【问题讨论】:

  • 你在调用它的第二秒就运行它,你可以全局定义箭头函数并调用 useCallback(newfunction(),[getData,page, values]);

标签: javascript reactjs react-hooks use-effect usecallback


【解决方案1】:

我设法通过简化代码并完全摆脱 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} />
    ) : ''}
  )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-11
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多