useContext() 不应该只用于低频率更新吗?(mobx-反应-精简版)

mle*_*ter 5 reactjs mobx-react mobx-react-lite

几乎所有示例(甚至官方文档)都mobx-react-lightuseContext()hook结合使用。

然而,React、许多文章和博客文章建议不要 useContext()用于中/高频更新。状态不是可以非常频繁地更新的东西吗?

应该将包与钩子结合使用还是会出现性能问题?

Dan*_*ila 4

useContext()仅用于获取您的商店值(参考),并且该值不会经常更新,通常您只设置一次商店,之后就不再触及它。当您使用操作时,您只会更改商店的可观察值,而不更改商店本身。所以基本上Context仅用于将存储的引用传递到树上,之后所有工作仅由 MobX 执行。

MobX 文档中的示例:

import {observer} from 'mobx-react-lite'
import {createContext, useContext} from "react"

const TimerContext = createContext<Timer>()

const TimerView = observer(() => {
    // Grab the timer from the context.
    const timer = useContext(TimerContext) // See the Timer definition above.
    return (
        <span>Seconds passed: {timer.secondsPassed}</span>
    )
})

ReactDOM.render(
    <TimerContext.Provider value={new Timer()}
        <TimerView />
    </TimerContext.Provider>,
    document.body
)
Run Code Online (Sandbox Code Playgroud)

因此,当您渲染应用程序时,您将值传递new Timer()TimerContext.Provider一次,之后它就永远不会被更改或更新。甚至文档也说:

请注意,我们不建议将 Provider 的值替换为其他提供商的值。使用 MobX,应该不需要这样做,因为共享的 observable 可以自行更新。

但是,如果您没有 SSR 或者不测试您的应用程序,那么您甚至根本不需要使用 Context,您只需使用全局变量/单例作为您的存储,它就会完美地工作。

例子:

// Initialize timer somewhere
export const myTimer = new Timer()

// You can use directly in the same file or import somewhere else
import { myTimer } from './file-with-your-timer'

// No props, `myTimer` is directly consumed from the closure or from another file
const TimerView = observer(() => <span>Seconds passed: {myTimer.secondsPassed}</span>)

ReactDOM.render(<TimerView />, document.body)
Run Code Online (Sandbox Code Playgroud)

引用自文档:

直接使用可观察量效果很好,但由于这通常会引入模块状态,因此这种模式可能会使单元测试变得复杂。相反,我们建议使用 React Context。

有关 React 最佳实践的更多信息:https://mobx.js.org/react-integration.html