Skip to content
This repository has been archived by the owner on Dec 31, 2020. It is now read-only.

Revert "Add test for proper reaction disposal in StrictMode" #145

Merged
merged 1 commit into from
May 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 6 additions & 14 deletions src/useObserver.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Reaction } from "mobx"
import { useDebugValue, useEffect, useRef } from "react"
import { useDebugValue, useRef } from "react"
import { printDebugValue } from "./printDebugValue"
import { isUsingStaticRendering } from "./staticRendering"
import { useForceUpdate } from "./utils"
import { useForceUpdate, useUnmount } from "./utils"

export type ForceUpdateHook = () => () => void

Expand All @@ -25,25 +25,17 @@ export function useObserver<T>(
const forceUpdate = wantedForceUpdateHook()

const reaction = useRef<Reaction | null>(null)
const committed = useRef(false)

if (!reaction.current) {
// First render for this component. Not yet committed.
reaction.current = new Reaction(`observer(${baseComponentName})`, () => {
// Observable has changed. Only force an update if we've definitely
// been committed.
if (committed.current) {
forceUpdate()
}
forceUpdate()
})
}

useDebugValue(reaction, printDebugValue)

useEffect(() => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing this useEffect hook to useLayoutEffect fixes the bug for me.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We certainly don't want to useLayoutEffect, that's bad for karma and stuff :) Besides, you said this PR alone fixed it, so I am not sure why would modify it even further. Please do provide an example, this is really hard to understand what kind of issue it actually is.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha, yeah, makes sense. Out of curiosity, what’s the reason that committed.current is set asynchronously in the useEffect hook rather than synchronously in the body of the useObserver hook?

Copy link

@meyer meyer May 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving committed.current = true; up and out of the useEffect hook also fixes the bug I was encountering.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't worry about this. It was really just an early experiment. See #121 for a proper solution and some details.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rad, thanks 🎉

committed.current = true
return () => reaction.current!.dispose()
}, [])
useUnmount(() => {
reaction.current!.dispose()
})

// render the original component, but have the
// reaction track the observables, so that rendering
Expand Down
8 changes: 7 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { useCallback, useState } from "react"
import { useCallback, useEffect, useState } from "react"

const EMPTY_ARRAY: any[] = []

export function useUnmount(fn: () => void) {
useEffect(() => fn, EMPTY_ARRAY)
}

export function useForceUpdate() {
const [, setTick] = useState(0)
Expand Down
42 changes: 0 additions & 42 deletions test/useObserver.test.tsx

This file was deleted.