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

React.js POST提交数据成功后表格未更新,如何正确使用useEffect实现同步?

问题根因

你的useEffect逻辑本身没有错误,出现新增数据不刷新的核心原因是两个:

  1. Table组件的useEffect依赖项为空数组,只会在组件首次挂载时执行1次拉取逻辑,后续后端数据更新后不会自动重新调用接口拉取最新数据
  2. AddForm和Table是两个独立组件,提交成功后没有通知Table刷新数据的机制
    另外你现有代码还存在一个隐藏问题:Table中渲染列表的key直接用了post对象,不符合React要求key为唯一基本类型值的规范,后续会引发渲染异常。

解决方案(改动最小,适合初学者)

采用状态提升+回调通知的方案实现数据同步,需要修改3处代码:

1. 修改Table组件

  • 新增refreshTrigger prop作为useEffect的依赖项,每次该值变化就重新拉取数据
  • 修正列表key为后端返回的唯一id
import React, { useState, useEffect } from "react";
import axios from "axios";

// 新增入参refreshTrigger
const Table = ({ refreshTrigger }) => {
  const [posts, setPosts] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const fetchPosts = async () => {
      setLoading(true);
      const res = await axios.get("http://localhost:3000/movies");
      setPosts(res.data);
      setLoading(false);
    };
    fetchPosts();
  }, [refreshTrigger]); // 依赖改为refreshTrigger,变化即重新拉取

  // 排序逻辑不变
  const [order, setOrder] = useState("ascending");
  const sorting = (s) => {
    if (order === "ascending") {
      const sorted = [...posts].sort((a, b) =>
        a[s].toLowerCase() > b[s].toLowerCase() ? 1 : -1
      );
      setPosts(sorted);
      setOrder("descending");
    }
    if (order === "descending") {
      const sorted = [...posts].sort((a, b) =>
        a[s].toLowerCase() < b[s].toLowerCase() ? 1 : -1
      );
      setPosts(sorted);
      setOrder("ascending");
    }
  };

  return (
    <div className="container">
      <table className="table table-bordered table-striped">
        <thead>
          <tr>
            <th className="click" onClick={() => sorting("name")}>Name</th>
            <th>Genre</th>
            <th>Rating</th>
            <th>Action</th>
          </tr>
        </thead>
        <tbody>
          {/* key改为post.id,不要用post对象 */}
          {posts.map((post) => (
            <tr key={post.id}>
              <td>{post.name}</td>
              <td>{post.genre}</td>
              <td>{post.rating}</td>
              <td>
                <button className="btn btn-outline-success">delete</button>
                <button className="btn btn-outline-warning">edit</button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

export default Table;

2. 修改AddForm组件

  • 新增onSubmitSuccess回调prop,提交成功后触发该回调通知父组件
  • 把e.preventDefault()移到逻辑最前面,避免异常时触发表单默认提交
  • 可选新增提交成功后清空表单的逻辑
import React, { useState } from "react";

// 新增入参onSubmitSuccess
function AddForm({ onSubmitSuccess }) {
  const [name, setName] = useState("");
  const [genre, setGenre] = useState("");
  const [rating, setRating] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault(); // 移到最前面
    fetch("http://localhost:3000/movies", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name, genre, rating }),
    })
      .then((response) => response.json())
      .then((response) => {
        console.log(response);
        // 提交成功触发回调
        onSubmitSuccess?.();
        // 清空表单
        setName("");
        setGenre("");
        setRating("");
      });
  };

  return (
    <div className="text-center">
      <h2>Add a New movie</h2>
      <form onSubmit={handleSubmit}>
        <label>Name:</label>
        <input
          name="name"
          type="text"
          required
          value={name}
          onChange={(e) => setName(e.target.value)}
        />
        <label>Genre:</label>
        <input
          name="genre"
          type="text"
          required
          value={genre}
          onChange={(e) => setGenre(e.target.value)}
        />
        <label>Rating:</label>
        <input
          name="rating"
          type="text"
          required
          value={rating}
          onChange={(e) => setRating(e.target.value)}
        />
        <button type="submit">Add</button>
      </form>
    </div>
  );
}

export default AddForm;

3. 修改两个组件的共同父组件(一般是App.jsx)

维护一个刷新触发器状态,收到AddForm的提交成功通知后更新触发器,触发Table重新拉取数据

import { useState } from "react";
import Table from "./Table";
import AddForm from "./AddForm";

function App() {
  // 刷新触发器,数值变化即代表需要刷新表格
  const [refreshTrigger, setRefreshTrigger] = useState(0);

  const handleAddSuccess = () => {
    // 数值+1触发变化
    setRefreshTrigger(prev => prev + 1);
  };

  return (
    <div>
      <AddForm onSubmitSuccess={handleAddSuccess} />
      <Table refreshTrigger={refreshTrigger} />
    </div>
  );
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:36:05