You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React修复无限循环后新增数据不刷新问题求助

React + Azure Table CRUD:解决无限循环与数据更新后不渲染问题

我是React新手,正在基于Azure Table构建简单CRUD应用。原本代码可正常获取数据并渲染,表单提交至Azure Table的功能也正常,但出现了无限循环问题。经查阅资料调整代码,将fetch请求移入useCallback后解决了无限循环,但现在新增数据提交后组件不再重新渲染。如何实现无无限循环且数据更新后自动渲染的效果?

现有组件代码

DATA LAYOUT COMPONENT

import React, { useCallback, useState, useEffect } from 'react';
import axios from 'axios';

const AzureTableComponent = () => {
const [tableData, setTableData] = useState([]);

const fetchData = useCallback(async () => {
    try {
      // [redacted] 账号、表名、SAS Token等配置

      const url = `https://${account}.table.core.windows.net/${tableName}?${sasToken}`;
      const response = await axios.get(url);
      console.log(response.data.value);

      
      setTableData(response.data.value);
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  }, []); 

  useEffect(() => {
    fetchData();
  }, [fetchData]);

return (
  <div className="container">
    <h1>Azure Table Data</h1>
    <div className="row">
      {tableData.map(item => (
        <div key={item.RowKey} data-key={item.RowKey} className="col-md-4 mb-3">
          <div className="card">
            <div className="card-body">
              <h5 className="card-title">{item.FirstName}</h5>
              <p className="card-text">{item.LastName}</p>
            </div>
          </div>
        </div>
      ))}
    </div>
  </div>
);
};

export default AzureTableComponent;

FORM COMPONENT

import React, { useState } from 'react';
import { TableClient } from '@azure/data-tables';

function NameForm() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');

  // [redacted] 账号名、凭证等配置

  const handleSubmit = async (event) => {
    event.preventDefault();

    
    const client = new TableClient(`https://${accountName}.table.core.windows.net`, credential);
  

    try {
     
      await client.createEntity({
        PartitionKey: 'new Date().getTime().toString()',
        RowKey: new Date().getTime().toString(),
        FirstName: firstName,
        LastName: lastName
      });
      console.log('Data submitted successfully.');
     
      setFirstName('');
      setLastName('');
    } catch (error) {
      console.error('Error submitting data:', error);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        First Name:
        <input
          type="text"
          value={firstName}
          onChange={(event) => setFirstName(event.target.value)}
        />
      </label>
      <br />
      <label>
        Last Name:
        <input
          type="text"
          value={lastName}
          onChange={(event) => setLastName(event.target.value)}
        />
      </label>
      <br />
      <button type="submit">Submit</button>
    </form>
  );
}

export default NameForm;

PARENT COMPONENT

import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css'
import AzureTableComponent from './components/dataCards'
import NameForm from './components/submitForm'

function App() {
  // const [count, setCount] = useState(0)

  return (
    <>
      <AzureTableComponent />
      <NameForm />
    </>
  )
}

export default App

解决方案

1. 状态提升 + 触发数据刷新

当前两个子组件完全独立,表单提交后无法通知数据组件重新拉取数据。需要在父组件中维护一个"刷新触发信号",表单提交成功后更新该信号,数据组件监听信号变化重新执行数据拉取。

修改父组件:

import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css'
import AzureTableComponent from './components/dataCards'
import NameForm from './components/submitForm'

function App() {
  const [refreshTrigger, setRefreshTrigger] = useState(0);

  // 提交成功后触发刷新的回调
  const onDataSubmitted = () => {
    setRefreshTrigger(prev => prev + 1); // 用递增数值作为变化信号
  }

  return (
    <>
      <AzureTableComponent refreshTrigger={refreshTrigger} />
      <NameForm onDataSubmitted={onDataSubmitted} />
    </>
  )
}

export default App

修改表单组件:

提交成功后调用父组件传入的刷新回调:

// 接收父组件的回调参数
function NameForm({ onDataSubmitted }) {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');

  // [redacted] 账号名、凭证等配置

  const handleSubmit = async (event) => {
    event.preventDefault();

    const client = new TableClient(`https://${accountName}.table.core.windows.net`, credential);

    try {
      // 修正原代码PartitionKey的引号问题,确保执行时间戳函数
      await client.createEntity({
        PartitionKey: new Date().getTime().toString(),
        RowKey: new Date().getTime().toString(),
        FirstName: firstName,
        LastName: lastName
      });
      console.log('Data submitted successfully.');
      setFirstName('');
      setLastName('');
      // 触发父组件的刷新信号
      onDataSubmitted();
    } catch (error) {
      console.error('Error submitting data:', error);
    }
  };

  // ... 返回表单JSX部分不变
}

export default NameForm;

修改数据组件:

监听refreshTrigger的变化,触发数据拉取:

const AzureTableComponent = ({ refreshTrigger }) => {
const [tableData, setTableData] = useState([]);

const fetchData = useCallback(async () => {
    try {
      // [redacted] 账号、表名、SAS Token等配置

      const url = `https://${account}.table.core.windows.net/${tableName}?${sasToken}`;
      const response = await axios.get(url);
      console.log(response.data.value);

      
      setTableData(response.data.value);
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  }, []); 

  // 新增refreshTrigger作为依赖,信号变化时重新拉取数据
  useEffect(() => {
    fetchData();
  }, [fetchData, refreshTrigger]);

// ... 返回渲染JSX部分不变
};

export default AzureTableComponent;

2. 规范useCallback依赖(可选)

如果fetchData中用到了外部变量(如account、tableName、sasToken),必须将这些变量加入useCallback的依赖数组,避免捕获旧值导致请求错误:

const fetchData = useCallback(async () => {
    // ... 请求代码
  }, [account, tableName, sasToken]); // 加入所有用到的外部依赖

3. 性能优化:缓存TableClient

表单组件中每次提交都创建新的TableClient,可将其移到组件外部或用useMemo缓存,减少重复创建开销:

// 移到组件外部,避免重复实例化
const client = new TableClient(`https://${accountName}.table.core.windows.net`, credential);

function NameForm({ onDataSubmitted }) {
  // ... 其余代码不变
}

针对你的疑问解答

  • 是否需要新增useState来处理更新后的数据? 不需要额外维护本地数据副本,通过触发重新拉取Azure Table的最新数据即可保证渲染内容与后端一致。
  • 是否需要将fetchData作为依赖传入useCallback? 不需要,useCallback的依赖是其内部用到的外部变量,fetchData本身是useCallback生成的函数,你之前在useEffect中传入fetchData作为依赖的写法是正确的,新增refreshTrigger后就能触发重新执行。

内容的提问来源于stack exchange,提问作者OMGDrAcula

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 08:42:06