MobX observable 未被跟踪
MobX observable not being tracked
我对使用 MobX 还很陌生,一直在尝试用它来检测 window 我的 React-Typescript 应用程序中的调整大小事件。这是我的代码:
App.tsx:
import { computed } from "mobx";
import { observer } from "mobx-react";
import type { Breakpoint } from "./display_size_observer";
import { DisplaySizeObserver } from "./display_size_observer";
import "./styles.css";
const ChildComponent = ({ size }: { size: Breakpoint }) => {
return <p>Size: {size}</p>;
};
export default function App() {
const displaySize = computed(() => DisplaySizeObserver.size);
const Child = observer(() => <ChildComponent size={displaySize.get()} />);
return <Child />;
}
display_size_observer.ts:
import { observable, action } from "mobx";
export type Breakpoint = "small" | "medium" | "large";
const BreakpointSmall: number = 375;
const BreakpointMedium: number = 768;
const getSizeAsBreakpoint = (size: number) => {
if (size <= BreakpointSmall) {
return "small";
} else if (size <= BreakpointMedium) {
return "medium";
}
return "large";
};
const getWindowSize = () => {
return getSizeAsBreakpoint(window.innerWidth);
};
const DisplaySizeObserverFactory = (() => {
let instance: DisplaySizeObserver;
class DisplaySizeObserver {
@observable.ref
size: Breakpoint = getWindowSize();
constructor() {
window.addEventListener("resize", this.handleResize);
}
@action
private handleResize() {
const newSize = getWindowSize();
if (!this.size || this.size !== newSize) {
this.size = newSize;
console.log("Updating size to:", this.size);
}
}
}
return {
getInstance: () => {
if (!instance) {
instance = new DisplaySizeObserver();
}
return instance;
}
};
})();
export const DisplaySizeObserver = DisplaySizeObserverFactory.getInstance();
Link 到 codesandbox: https://codesandbox.io/s/admiring-mendel-h0kcb?file=/src/display_size_observer.ts:0-1169&resolutionWidth=446&resolutionHeight=675
根据我的理解,ChildComponent
在 observer
中应该跟踪显示大小的更新并相应地重新呈现 Child
。然而,这似乎并没有发生。
如果能帮助我理解我做错了什么以及如何解决它,我将不胜感激。
有几处出错了:
在 class 构造函数中添加 makeObservable(this);
。从 MobX v6 开始它是必需的。更多信息:
handleResize
函数在此处丢失上下文:window.addEventListener('resize', this.handleResize);
,因为它既不是绑定函数也不是箭头函数。使其成为箭头函数。
不要用@observable.ref
代替size
,@observable
就够了
每个使用 observable
值的组件都应该包装到 observer
HOC 中。不要做你在应用程序中做的这些奇怪的事情,就像那样重写它:
const ChildComponent = observer(() => {
return <p>Size: {DisplaySizeObserver.size}</p>;
});
export default function App() {
return <ChildComponent />;
}
或者如果你想让 ChildComponent
接受 props 然后将 App 包装在 observer
中并只传递 props:
const App = observer(() => {
return <ChildComponent size={DisplaySizeObserver.size} />;
})
export default App
我对使用 MobX 还很陌生,一直在尝试用它来检测 window 我的 React-Typescript 应用程序中的调整大小事件。这是我的代码:
App.tsx:
import { computed } from "mobx";
import { observer } from "mobx-react";
import type { Breakpoint } from "./display_size_observer";
import { DisplaySizeObserver } from "./display_size_observer";
import "./styles.css";
const ChildComponent = ({ size }: { size: Breakpoint }) => {
return <p>Size: {size}</p>;
};
export default function App() {
const displaySize = computed(() => DisplaySizeObserver.size);
const Child = observer(() => <ChildComponent size={displaySize.get()} />);
return <Child />;
}
display_size_observer.ts:
import { observable, action } from "mobx";
export type Breakpoint = "small" | "medium" | "large";
const BreakpointSmall: number = 375;
const BreakpointMedium: number = 768;
const getSizeAsBreakpoint = (size: number) => {
if (size <= BreakpointSmall) {
return "small";
} else if (size <= BreakpointMedium) {
return "medium";
}
return "large";
};
const getWindowSize = () => {
return getSizeAsBreakpoint(window.innerWidth);
};
const DisplaySizeObserverFactory = (() => {
let instance: DisplaySizeObserver;
class DisplaySizeObserver {
@observable.ref
size: Breakpoint = getWindowSize();
constructor() {
window.addEventListener("resize", this.handleResize);
}
@action
private handleResize() {
const newSize = getWindowSize();
if (!this.size || this.size !== newSize) {
this.size = newSize;
console.log("Updating size to:", this.size);
}
}
}
return {
getInstance: () => {
if (!instance) {
instance = new DisplaySizeObserver();
}
return instance;
}
};
})();
export const DisplaySizeObserver = DisplaySizeObserverFactory.getInstance();
Link 到 codesandbox: https://codesandbox.io/s/admiring-mendel-h0kcb?file=/src/display_size_observer.ts:0-1169&resolutionWidth=446&resolutionHeight=675
根据我的理解,ChildComponent
在 observer
中应该跟踪显示大小的更新并相应地重新呈现 Child
。然而,这似乎并没有发生。
如果能帮助我理解我做错了什么以及如何解决它,我将不胜感激。
有几处出错了:
在 class 构造函数中添加
makeObservable(this);
。从 MobX v6 开始它是必需的。更多信息:handleResize
函数在此处丢失上下文:window.addEventListener('resize', this.handleResize);
,因为它既不是绑定函数也不是箭头函数。使其成为箭头函数。不要用
@observable.ref
代替size
,@observable
就够了每个使用
observable
值的组件都应该包装到observer
HOC 中。不要做你在应用程序中做的这些奇怪的事情,就像那样重写它:
const ChildComponent = observer(() => {
return <p>Size: {DisplaySizeObserver.size}</p>;
});
export default function App() {
return <ChildComponent />;
}
或者如果你想让 ChildComponent
接受 props 然后将 App 包装在 observer
中并只传递 props:
const App = observer(() => {
return <ChildComponent size={DisplaySizeObserver.size} />;
})
export default App