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

React中使用setTimeout与useEffect实现延迟效果及解决DOM不更新问题

问题根因

你没有遵循React状态不可变的更新规则,直接原地修改状态不会触发组件重渲染:

  • 两次对activeChat.messages执行push操作都属于原地修改数组,activeChat状态的引用没有发生变化,React无法检测到状态变更,自然不会主动触发DOM更新。你看到的下次交互时才更新,是因为交互触发了message等其他状态的更新,顺带把之前未生效的修改渲染了出来。

修正方案

所有涉及activeChat的更新都需要调用setActiveChat,传入新的状态对象,禁止直接修改原状态:

  1. 调整提交消息的更新逻辑
  2. 调整useEffect内setTimeout中的更新逻辑,建议使用函数式更新避免闭包问题

修正后完整代码

import React, { useEffect, useState } from 'react';
import { render } from 'react-dom';

interface Chat {
  messages: string[];
  poster: string;
}

const App = () => {
  const [activeChat, setActiveChat] = useState<Chat>({
    poster: 'Adam',
    messages: ['one', 'two', 'three'],
  });

  const [message, setMessage] = useState('');
  const [isBotChat, setIsBotChat] = useState(false);

  useEffect(() => {
    if (isBotChat) {
      setIsBotChat(false);
      setTimeout(() => {
        // 使用函数式更新,基于最新状态生成新状态
        setActiveChat(prev => ({
          ...prev,
          messages: [...prev.messages, 'dsadsadsada']
        }))
        console.log('setTimeout completed');
      }, 500);
    }
  }, [isBotChat]);

  const handleSubmit = (e) => {
    e.preventDefault();

    if (message !== '') {
      // 传入新的状态对象,触发重渲染
      setActiveChat(prev => ({
        ...prev,
        messages: [...prev.messages, message]
      }))
      setMessage('');
      setIsBotChat(true);
    }
  };

  return (
    <div>
      <h1>Active Chat</h1>
      <div>
        {activeChat?.messages.map((m, index) => (
          <div key={index}>{m}</div>
        ))}
      </div>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          value={message}
          onChange={(e) => setMessage(e.currentTarget.value)}
        />
        <button type="submit">Send Message</button>
      </form>
    </div>
  );
};

render(<App />, document.getElementById('root'));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:45:01