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

Mobx observer在React中未触发重渲染,求排查方案

问题分析

你遇到的核心问题是每次App组件渲染时都会创建一个全新的playerListStore实例。因为createList()直接写在组件函数内部,组件每一次重渲染(包括初始渲染)都会执行这个函数生成新的store对象,导致:

  1. useEffect依赖playerListStore,每次store实例变化都会重新触发fetchPlayers,但之前的store更新后,组件已经切换到新的store实例,根本不会监听旧store的变化
  2. 即使数据成功获取并更新了旧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);

额外优化建议

  1. 替换列表key:建议用API返回的球员唯一id作为列表项的key(不要用index),能提升列表渲染性能
  2. 规范MST数组更新:Mobx-State-Tree的数组类型推荐用replace方法替换内容,比直接赋值更符合框架规范,修改store.js里的setPlayers:
setPlayers(newPlayers) {
    self.players.replace(newPlayers)
}

修改完成后,store实例会被持久化,当fetchPlayers更新store的players数组时,observer会检测到状态变化并触发组件重渲染,就能正常展示球员数据了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:40:23