You need to enable JavaScript to run this app. React经axios向Express发POST存库后页面不自动重渲染,需手动刷新
优惠活动
大模型
产品
解决方案
定价
更多

React经axios向Express发POST存库后页面不自动重渲染,需手动刷新

点击发布后内容不自动更新的原因与解决方法

核心问题原因

  • ViewerList中的useEffect设置了空依赖数组,仅会在组件首次挂载时发起一次GET请求拉取数据,后续没有组件重挂载的触发条件时,永远不会再次拉取数据库的最新内容
  • Poster与ViewerList是相互独立的组件,Poster完成POST请求写入数据库后,没有任何跨组件通信机制通知ViewerList重新获取数据,因此只有手动刷新页面触发整页重加载,才会执行ViewerList的初始拉取逻辑,展示新发布的内容。

具体实现方法

推荐方案:状态提升(无额外依赖,适配当前项目规模)

把数据列表的状态、拉取数据的逻辑上移到两个组件的共同父组件中统一管理,实现跨组件联动:

  1. 父组件持有列表状态,封装可复用的列表拉取方法
  2. 将拉取方法作为属性传给Poster,在POST请求成功的回调中调用该方法,触发列表重新拉取
  3. 将父组件维护的列表数据作为属性传给ViewerList完成渲染

对应的代码调整:

  1. 共同父组件示例:
import { useState, useEffect } from 'react';
import Poster from './Poster';
import ViewerList from './ViewerList';
import axios from 'axios';

const url = "http://localhost:3001/";

function Home() {
  // 上移的列表状态
  const [myData, setMyData] = useState([]);

  // 封装通用拉取方法
  const fetchList = () => {
    axios.get(url)
      .then(res => setMyData(res.data))
      .catch(err => console.log(err));
  }

  // 首次挂载时拉取初始数据
  useEffect(() => {
    fetchList();
  }, [])

  return (
    <div>
      {/* 将拉取方法传给Poster,支持提交成功后触发更新 */}
      <Poster onPostSuccess={fetchList} />
      {/* 将列表数据传给ViewerList渲染 */}
      <ViewerList listData={myData} />
    </div>
  )
}
  1. 调整Poster组件的逻辑:

原代码中同时使用受控value={topic}和ref读取文本域值属于重复逻辑,直接使用state值提交即可,无需额外引入ref

import React, { useState } from 'react';
import axios from "axios";
import qs from "qs";

function Poster({ onPostSuccess }) {
  const [topic, topicSetter] = useState("");
  const url = "http://localhost:3001/";

  function update(ev) {
    topicSetter(ev.target.value)        
  }
   
  function Submit(event){
    event.preventDefault();
    // 直接使用受控state值提交
    const toPostTopic = {"idea": topic};
    axios.post(url, qs.stringify(toPostTopic))
      .then((res)=>{
        console.log(res.data); 
        // POST成功后触发父组件重新拉取最新列表
        onPostSuccess();
      })
    // 清空输入框
    topicSetter("");
  }

  return(
    <form onSubmit={(e)=>Submit(e)}>
      <textarea 
        placeholder="Tell us your perfect idea..." 
        onChange={update} 
        type="text"
        cols="50" rows="2" maxLength="100" 
        className="table table-boarded poster-form"
        name="ideaPosted" 
        value={topic}
      />
      <button type="submit" className="btn btn-primary btn-lg btn-block poster-form-btn">Post</button>
    </form>
  );
}

export default Poster;
  1. 调整ViewerList组件,移除内部拉取逻辑,直接接收父组件传入的列表数据渲染:
import React from 'react';
import Viewer from "./Viewer"

function ViewerList({ listData }) {
  return (
    <div> 
      {listData.map((ide)=> <Viewer key={ide.key} idea={ide.idea}/>)} 
    </div>
  )
}

export default ViewerList;

其他可选方案

如果项目后续组件层级较多,也可以通过Context、Redux等全局状态管理工具共享列表状态,在POST请求成功后直接更新全局状态中的列表数据,省去重复请求的开销,不过对于当前规模的应用,状态提升的实现成本更低。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 16:15:04