React使用render方法更新UI时新元素生成但界面未更新问题咨询
问题解答
你的原有认知是错误的
- 单纯调用函数组件生成React元素,完全不会触发UI更新。组件函数本质只是一个返回React元素的普通JS函数,你直接调用它只会在内存里生成一个JS对象,这个对象如果没有交给React的渲染流程处理,React根本感知不到它的存在,自然也不会去更新真实DOM。
- 你写的代码问题就出在
setInterval(Clock, 1000)这行:你每秒只是执行了Clock函数拿到了新元素,但没有把这个新元素传递给ReactDOM.render(),所以UI不会有任何变化。
对官方文档说明的正确理解
官方说的「更新UI的唯一方式是创建新元素并将其传递给ReactDOM.render()」是针对根节点全量渲染的场景:
如果你不使用React的状态管理能力(比如useState、setState这类API),要更新根节点下的UI,确实只有手动传新元素给ReactDOM.render这一种途径。
而后续你在组件内部使用状态更新API的时候,React会自动帮你触发组件的重渲染、生成新的元素树、做diff更新DOM,这个过程是React封装好的,不需要你手动调用ReactDOM.render,但本质上依然遵循「创建新元素再触发渲染更新」的逻辑,只是不需要你手动处理根渲染的步骤。
官方示例和你代码的核心差异
官方示例的tick函数每次执行都会主动调用ReactDOM.render,把新生成的带最新时间的<Clock />元素传给React,这时候React才会执行渲染逻辑,对比新旧元素的差异,更新对应的DOM节点,所以UI会每秒刷新。
更符合React开发习惯的写法
如果不想每次手动调用ReactDOM.render,可以把Clock改造成有状态组件,用React自带的状态更新能力触发自动重渲染:
import { useState, useEffect } from 'react'; import ReactDOM from 'react-dom'; function Clock() { // 用state存时间,更新state会自动触发组件重渲染 const [time, setTime] = useState(new Date()); useEffect(() => { const timer = setInterval(() => { setTime(new Date()); }, 1000); // 组件卸载时清除定时器 return () => clearInterval(timer); }, []); return ( <div> <h1>Hello, world!</h1> <h2>It is {time.toLocaleTimeString()}.</h2> </div> ); } // 只需要调用一次根渲染即可 ReactDOM.render(<Clock />, document.getElementById('root'));
内容的提问来源于stack exchange,提问作者Dilu
相关产品推荐
相关产品推荐

