Mobx observer在React中未触发重渲染,求排查方案
问题分析
你遇到的核心问题是每次App组件渲染时都会创建一个全新的playerListStore实例。因为createList()直接写在组件函数内部,组件每一次重渲染(包括初始渲染)都会执行这个函数生成新的store对象,导致:
useEffect依赖playerListStore,每次store实例变化都会重新触发fetchPlayers,但之前的store更新后,组件已经切换到新的store实例,根本不会监听旧store的变化- 即使数据成功获取并更新了旧store,当前组件使用的是新的空store,自然不会触发重渲染展示数据
解决方案
需要确保组件生命周期内只创建一次store实例,推荐用useState来持久化store:
修改后的App.js
import { useEffect, useState } from "react"; import { createList } from "./mst/createList"; import { observer } from "mobx-react-lite"; import { values } from "mobx" function App() { // 用useState只初始化一次store,确保整个组件生命周期内实例唯一 const [playerListStore] = useState(() => createList()); useEffect(() => { playerListStore.fetchPlayers(); }, [playerListStore]); console.log(playerListStore.players); return ( <div className="App"> <h1>NBA Players</h1> <ul> {values(playerListStore.players).map((player, index) => ( <li key={index}> <p>{player.firstName}</p> </li> ))} </ul> </div> ) } export default observer(App);
额外优化建议
- 替换列表key:建议用API返回的球员唯一
id作为列表项的key(不要用index),能提升列表渲染性能 - 规范MST数组更新:Mobx-State-Tree的数组类型推荐用
replace方法替换内容,比直接赋值更符合框架规范,修改store.js里的setPlayers:
setPlayers(newPlayers) { self.players.replace(newPlayers) }
修改完成后,store实例会被持久化,当fetchPlayers更新store的players数组时,observer会检测到状态变化并触发组件重渲染,就能正常展示球员数据了。
内容的提问来源于stack exchange,提问作者Shiyuan
相关产品推荐
相关产品推荐

