为何我的Todo List应用中TaskList组件未重新渲染?
问题分析与解决方案
核心问题是你在组件函数内部直接声明了taskList,每次组件渲染时这个变量都会被重新初始化,导致MobX的observer无法持续追踪它的变化,组件也不会因为它的更新触发重新渲染。
解决步骤:
- 持久化observable对象:用
useRef保存taskList,确保组件整个生命周期内引用不变,避免每次渲染重置状态。 - 简化action调用:
makeAutoObservable已经自动将对象的修改操作包装为action,不需要手动用action()包裹。 - 添加React列表key:给
map生成的元素添加唯一key,符合React规范。
修改后的完整代码:
interface Task { task: string; } export default observer(function TaskList() { const [update, setUpdate] = useState<string>(''); // 用useRef持久化observable对象 const taskListRef = useRef(makeAutoObservable({ tasks: [] as Task[] })); const taskList = taskListRef.current; useEffect(() => { fetchData(); }, []); const fetchData = async () => { try { const response: any = await axios.get('http://localhost:5000/data'); // 直接修改即可,makeAutoObservable已自动处理action taskList.tasks.push(...response.data.recordset); } catch (error) { console.error(error); } }; const onChangeValue = (e: any) => { setUpdate(e.target.value); }; return ( <div> <p> update input <input onChange={onChangeValue} value={update} /> </p> {taskList.tasks.map((value, key) => ( <div key={key}> <div> <p> {value.task} <DeleteTask value={value} taskList={taskList} /> <UpdateTask value={update} current={value} taskList={taskList} /> </p> </div> </div> ))} </div> ); });
补充说明:
useRef的作用是在组件渲染周期中保持引用的稳定性,这样MobX的响应系统能正确关联到同一个observable对象,当taskList.tasks变化时,observer组件会自动重新渲染。- 如果任务列表需要在多个组件间共享,也可以将
taskList提取为组件外部的全局MobX store,效果类似但更适合跨组件状态管理。
内容的提问来源于stack exchange,提问作者Chan Kim
相关产品推荐
相关产品推荐

