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

Use Finalization registry to dispose reactions of uncommitted components #332

Merged
merged 12 commits into from
Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: 2.1
executors:
my-executor:
docker:
- image: circleci/node:11
- image: circleci/node:14
danielkcz marked this conversation as resolved.
Show resolved Hide resolved
environment:
CI: "yes"

Expand Down
217 changes: 109 additions & 108 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,110 +1,111 @@
{
"name": "mobx-react-lite",
Bnaya marked this conversation as resolved.
Show resolved Hide resolved
"version": "3.0.1",
"description": "Lightweight React bindings for MobX based on React 16.8+ and Hooks",
"main": "lib/index.js",
"unpkg": "dist/mobxreactlite.umd.production.min.js",
"jsdelivr": "dist/mobxreactlite.umd.production.min.js",
"module": "es/index.js",
"jsnext:main": "es/index.js",
"react-native": "es/index.js",
"types": "dist/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/mobxjs/mobx-react-lite.git"
"name": "mobx-react-lite",
"version": "3.0.1",
"description": "Lightweight React bindings for MobX based on React 16.8+ and Hooks",
"main": "lib/index.js",
"unpkg": "dist/mobxreactlite.umd.production.min.js",
"jsdelivr": "dist/mobxreactlite.umd.production.min.js",
"module": "es/index.js",
"jsnext:main": "es/index.js",
"react-native": "es/index.js",
"types": "dist/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/mobxjs/mobx-react-lite.git"
},
"files": [
"dist/",
"lib/",
"es/",
"batching*"
],
"scripts": {
"prettier": "prettier --write \"./{src,test}/*.{js,ts,tsx}\"",
"lint": "eslint . --ext .js,.ts,.tsx",
"validate": "tsc --noEmit",
"test": "jest --watch",
"test:ci": "jest -i --coverage",
"size": "size-limit",
"coverage": "jest --coverage",
"prebuild": "rimraf dist lib es",
"build": "yarn build:commonjs && yarn build:es && yarn build:umd",
"build:commonjs": "tsc --project tsconfig.build.cjs.json",
"build:es": "tsc --project tsconfig.build.es.json",
"build:umd": "tsdx build --name mobxReactLite --format=umd --tsconfig tsconfig.build.es.json",
"release": "yarn build && yarn changeset publish"
},
"author": "Daniel K.",
"license": "MIT",
"bugs": {
"url": "https://github.com/mobxjs/mobx/issues"
},
"homepage": "https://mobx.js.org",
"peerDependencies": {
"mobx": "^6.0.0",
"react": "^16.8.0"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"files": [
"dist/",
"lib/",
"es/",
"batching*"
],
"scripts": {
"prettier": "prettier --write \"./{src,test}/*.{js,ts,tsx}\"",
"lint": "eslint . --ext .js,.ts,.tsx",
"validate": "tsc --noEmit",
"test": "jest --watch",
"test:ci": "jest -i --coverage",
"size": "size-limit",
"coverage": "jest --coverage",
"prebuild": "rimraf dist lib es",
"build": "yarn build:commonjs && yarn build:es && yarn build:umd",
"build:commonjs": "tsc --project tsconfig.build.cjs.json",
"build:es": "tsc --project tsconfig.build.es.json",
"build:umd": "tsdx build --name mobxReactLite --format=umd --tsconfig tsconfig.build.es.json",
"release": "yarn build && yarn changeset publish"
},
"author": "Daniel K.",
"license": "MIT",
"bugs": {
"url": "https://github.com/mobxjs/mobx/issues"
},
"homepage": "https://mobx.js.org",
"peerDependencies": {
"mobx": "^6.0.0",
"react": "^16.8.0"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
},
"devDependencies": {
"@babel/core": "7.8.4",
"@babel/preset-env": "7.8.4",
"@changesets/changelog-github": "^0.2.7",
"@changesets/cli": "^2.11.0",
"@size-limit/preset-small-lib": "2.1.6",
"@size-limit/time": "2.1.6",
"@testing-library/jest-dom": "4.1.2",
"@testing-library/react": "9.3.0",
"@testing-library/react-hooks": "1.1.0",
"@types/jest": "24.0.19",
"@types/node": "12.7.12",
"@types/react": "16.9.6",
"@types/react-dom": "16.9.2",
"@typescript-eslint/eslint-plugin": "^2.19.2",
"@typescript-eslint/parser": "^2.19.2",
"coveralls": "3.0.7",
"eslint": "^6.1.0",
"eslint-plugin-react": "^7.18.3",
"husky": "3.0.9",
"jest": "24.9.0",
"jest-environment-jsdom": "24.9.0",
"jest-mock-console": "1.0.0",
"mobx": "^6.0.0-rc.7",
"prettier": "^1.19.1",
"pretty-quick": "^2.0.1",
"prompts": "^2.3.2",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-test-renderer": "16.10.2",
"rimraf": "3.0.0",
"semver": "^7.2.2",
"shelljs": "^0.8.3",
"shx": "0.3.2",
"ts-jest": "24.1.0",
"tsdx": "0.12.3",
"typescript": "3.6.4"
},
"keywords": [
"mobx",
"mobservable",
"react-component",
"react",
"reactjs",
"reactive",
"hooks",
"observer",
"useLocalObservable"
],
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
}
},
"dependencies": {}
}
"react-native": {
"optional": true
}
},
"devDependencies": {
"@babel/core": "7.8.4",
"@babel/preset-env": "7.8.4",
"@changesets/changelog-github": "^0.2.7",
"@changesets/cli": "^2.11.0",
"@size-limit/preset-small-lib": "2.1.6",
"@size-limit/time": "2.1.6",
"@testing-library/jest-dom": "4.1.2",
"@testing-library/react": "9.3.0",
"@testing-library/react-hooks": "1.1.0",
"@types/jest": "24.0.19",
"@types/node": "12.7.12",
"@types/react": "16.9.6",
"@types/react-dom": "16.9.2",
"@typescript-eslint/eslint-plugin": "^2.19.2",
"@typescript-eslint/parser": "^2.19.2",
"coveralls": "3.0.7",
"eslint": "^6.1.0",
"eslint-plugin-react": "^7.18.3",
"expose-gc": "^1.0.0",
"husky": "3.0.9",
"jest": "24.9.0",
"jest-environment-jsdom": "24.9.0",
"jest-mock-console": "1.0.0",
"mobx": "^6.0.0-rc.7",
"prettier": "^1.19.1",
"pretty-quick": "^2.0.1",
"prompts": "^2.3.2",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-test-renderer": "16.10.2",
"rimraf": "3.0.0",
"semver": "^7.2.2",
"shelljs": "^0.8.3",
"shx": "0.3.2",
"ts-jest": "24.1.0",
"tsdx": "0.12.3",
"typescript": "3.6.4"
},
"keywords": [
"mobx",
"mobservable",
"react-component",
"react",
"reactjs",
"reactive",
"hooks",
"observer",
"useLocalObservable"
],
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
}
},
"dependencies": {}
}
15 changes: 9 additions & 6 deletions src/useObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import React from "react"

import { printDebugValue } from "./utils/printDebugValue"
import {
createTrackingData,
addReactionToTrack,
IReactionTracking,
recordReactionAsCommitted,
scheduleCleanupOfReactionIfLeaked
recordReactionAsCommitted
} from "./utils/reactionCleanupTracking"
import { isUsingStaticRendering } from "./staticRendering"
import { useForceUpdate } from "./utils/utils"
Expand All @@ -20,6 +19,8 @@ export function useObserver<T>(fn: () => T, baseComponentName: string = "observe
return fn()
}

const [objectRetainedByReact] = React.useState({})
danielkcz marked this conversation as resolved.
Show resolved Hide resolved

const forceUpdate = useForceUpdate()

// StrictMode/ConcurrentMode/Suspense may mean that our component is
Expand Down Expand Up @@ -47,9 +48,11 @@ export function useObserver<T>(fn: () => T, baseComponentName: string = "observe
}
})

const trackingData = createTrackingData(newReaction)
reactionTrackingRef.current = trackingData
scheduleCleanupOfReactionIfLeaked(reactionTrackingRef)
Bnaya marked this conversation as resolved.
Show resolved Hide resolved
const trackingData = addReactionToTrack(
reactionTrackingRef,
newReaction,
objectRetainedByReact
)
}

const { reaction } = reactionTrackingRef.current!
Expand Down
12 changes: 12 additions & 0 deletions src/utils/FinalizationRegistryWrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
declare class FinalizationRegistryType<T> {
constructor(cleanup: (cleanupToken: T) => void)
register(object: object, cleanupToken: T, unregisterToken?: object): void
unregister(unregisterToken: object): void
}

declare const FinalizationRegistry: typeof FinalizationRegistryType | undefined

const FinalizationRegistryLocal =
typeof FinalizationRegistry === "undefined" ? undefined : FinalizationRegistry

export { FinalizationRegistryLocal as FinalizationRegistry }
Loading