如何解决react-refresh结合Mobx时部分组件无法自动更新的问题?
inject + observer Components First off: Yes, React Refresh should work seamlessly with MobX and mobx-react, but there's a known edge case when combining inject and observer HOCs—this is likely what's causing your partial update issue. Let's break down why this happens and how to fix it:
Why This Happens
React Refresh relies on tracking component identities and preserving state during hot updates. When you wrap a component with inject('rootStore')(observer(MyComponent)), you're creating a nested HOC structure. If your hot update logic doesn't properly target the final wrapped component (instead of the raw MyComponent), React Refresh can't swap in the updated version—hence the "App is up to date" log without actual page changes.
Step-by-Step Fixes
1. Fix Hot Update Accept Logic for Wrapped Components
Ensure your component file explicitly accepts updates for the fully wrapped component, not just the raw component. Here's how to adjust your UserProfile.js:
import React from 'react'; import { inject, observer } from 'mobx-react'; const UserProfile = ({ rootStore }) => { // Your component logic here return <div>{rootStore.someValue}</div>; }; // Wrap the component as usual export const WrappedUserProfile = inject('rootStore')(observer(UserProfile)); // Handle hot update correctly if (module.hot) { module.hot.accept('./UserProfile.js', () => { const { WrappedUserProfile: UpdatedComponent } = require('./UserProfile.js'); // Trigger React Refresh on the wrapped component if (window.ReactRefreshRuntime) { window.ReactRefreshRuntime.refresh(UpdatedComponent); } }); } export default WrappedUserProfile;
2. Verify React Refresh Webpack Plugin Configuration
Double-check your Webpack config to ensure the plugin isn't excluding your component directories, and that hot reloading is properly enabled:
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const webpack = require('webpack'); module.exports = { mode: 'development', devtool: 'cheap-module-source-map', // Required for React Refresh to work reliably plugins: [ new webpack.HotModuleReplacementPlugin(), new ReactRefreshWebpackPlugin({ exclude: /node_modules/, overlay: true, // Shows errors in-browser for easier debugging }), ], // If using webpack-dev-middleware + webpack-hot-middleware: devServer: { hot: true, liveReload: false, // Disable live reload to let HMR handle updates }, };
3. Check MobX & mobx-react Setup
For MobX 6.x, ensure your stores are initialized correctly (e.g., using makeAutoObservable or makeObservable). While this doesn't directly cause hot refresh issues, a misconfigured store can lead to unexpected subscription behavior that masks HOC-related problems.
4. Try Updating Dependencies (If Possible)
Your version of @pmmmwh/react-refresh-webpack-plugin (0.4.2) is a bit outdated. While it's compatible with React 16.13.1, newer versions (like 0.5.x, which supports Webpack 4) include fixes for HOC-related hot refresh edge cases. You can update it safely with:
npm install @pmmmwh/react-refresh-webpack-plugin@^0.5.10 --save-dev
5. Debug by Simplifying
To isolate the issue:
- Temporarily remove the
injectwrapper and check ifobserver(UserProfile)hot refreshes correctly. - If it works, re-add
injectand adjust the hot accept logic as shown in step 1.
Additional Context
Your experience mirrors common issues with React Hot Loader v4 and MobX—both tools struggle with HOC-wrapped components because they need to track the exact component identity that's rendered in the tree. React Refresh is more robust than RHL, but it still requires explicit handling for deeply wrapped components.
内容的提问来源于stack exchange,提问作者Kev

