Mobx Store 在嵌套输入范围内显示滞后。导致性能下降
Mobx Store shows lag in nested input range. Causes slow performance
我有一个简单的 MobX 存储 padding
和 padding2
,区别在于一个是对象:
import { observable, action, makeObservable } from "mobx"
export type Padding2 = {
horizontal: number
vertical: number
}
export interface IStore {
padding: number
updatePadding({ padding }: { padding: number }): void
padding2: Padding2
updatePadding2({ horizontal, vertical }: Partial<Padding2>): void
}
export class Store implements IStore {
padding = 100
padding2 = {
horizontal: 100,
vertical: 50,
}
constructor() {
makeObservable(this, {
padding: observable,
updatePadding: action.bound,
padding2: observable,
updatePadding2: action.bound,
})
}
updatePadding({ padding }: { padding: number }) {
this.padding = padding
}
updatePadding2({ horizontal, vertical }: Partial<Padding2>) {
if (horizontal) this.padding2.horizontal = horizontal
if (vertical) this.padding2.vertical = vertical
}
}
export const store = new Store()
我有一个简单的 <input type="range" />
比如:
import * as React from "react"
import { observer } from "mobx-react"
import "./styles.css"
import { useStore } from "./context"
const App = () => {
const store = useStore()
const { padding, updatePadding, padding2, updatePadding2 } = store
return (
<div>
<h1>MobX Slow Perf for Range</h1>
<h2>Padding</h2>
<input
type="range"
name="padding"
value={padding}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const padding = Number(e.target.value)
updatePadding({
padding,
})
}}
/>
<span>{padding} px</span>
<h2>Padding2</h2>
<input
type="range"
name="horizontal"
value={padding2.horizontal}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const horizontal = Number(e.target.value)
updatePadding2({
horizontal,
})
}}
/>
<span>{padding2.horizontal} px</span>
</div>
)
}
export default observer(App)
当我在 padding
(第一个滑块)上使用滑块时,它从 100
平滑地移动到 0
,但是当我在 padding2
(第二个滑块)上使用时滑块)它显示出明显的滞后。
这是一个最小的 Codesandbox → https://codesandbox.io/s/mobx-range-slow-perf-3zobu?file=/src/App.tsx
如何在不为 padding2
使用 React.useState()
等其他本地状态的情况下解决它?
这里的细微错误是 updatePadding
检查 horizontal
或 vertical
是否为 truthy。这意味着 0 returns 的值是 false,然后商店根本不会更新。因此,当您快速向左拖动它时,滑块会跳到 0,但它的值不会更新。
要解决此问题,您需要明确检查它们是否 undefined
updatePadding2({ horizontal, vertical }: Partial<Padding2>) {
if (horizontal !== undefined) this.padding2.horizontal = horizontal;
if (vertical !== undefined) this.padding2.vertical = vertical;
}
我有一个简单的 MobX 存储 padding
和 padding2
,区别在于一个是对象:
import { observable, action, makeObservable } from "mobx"
export type Padding2 = {
horizontal: number
vertical: number
}
export interface IStore {
padding: number
updatePadding({ padding }: { padding: number }): void
padding2: Padding2
updatePadding2({ horizontal, vertical }: Partial<Padding2>): void
}
export class Store implements IStore {
padding = 100
padding2 = {
horizontal: 100,
vertical: 50,
}
constructor() {
makeObservable(this, {
padding: observable,
updatePadding: action.bound,
padding2: observable,
updatePadding2: action.bound,
})
}
updatePadding({ padding }: { padding: number }) {
this.padding = padding
}
updatePadding2({ horizontal, vertical }: Partial<Padding2>) {
if (horizontal) this.padding2.horizontal = horizontal
if (vertical) this.padding2.vertical = vertical
}
}
export const store = new Store()
我有一个简单的 <input type="range" />
比如:
import * as React from "react"
import { observer } from "mobx-react"
import "./styles.css"
import { useStore } from "./context"
const App = () => {
const store = useStore()
const { padding, updatePadding, padding2, updatePadding2 } = store
return (
<div>
<h1>MobX Slow Perf for Range</h1>
<h2>Padding</h2>
<input
type="range"
name="padding"
value={padding}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const padding = Number(e.target.value)
updatePadding({
padding,
})
}}
/>
<span>{padding} px</span>
<h2>Padding2</h2>
<input
type="range"
name="horizontal"
value={padding2.horizontal}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const horizontal = Number(e.target.value)
updatePadding2({
horizontal,
})
}}
/>
<span>{padding2.horizontal} px</span>
</div>
)
}
export default observer(App)
当我在 padding
(第一个滑块)上使用滑块时,它从 100
平滑地移动到 0
,但是当我在 padding2
(第二个滑块)上使用时滑块)它显示出明显的滞后。
这是一个最小的 Codesandbox → https://codesandbox.io/s/mobx-range-slow-perf-3zobu?file=/src/App.tsx
如何在不为 padding2
使用 React.useState()
等其他本地状态的情况下解决它?
这里的细微错误是 updatePadding
检查 horizontal
或 vertical
是否为 truthy。这意味着 0 returns 的值是 false,然后商店根本不会更新。因此,当您快速向左拖动它时,滑块会跳到 0,但它的值不会更新。
要解决此问题,您需要明确检查它们是否 undefined
updatePadding2({ horizontal, vertical }: Partial<Padding2>) {
if (horizontal !== undefined) this.padding2.horizontal = horizontal;
if (vertical !== undefined) this.padding2.vertical = vertical;
}