Skip to content

Commit

Permalink
refactor: add useMotionReduced to prevent infinite animation calcul…
Browse files Browse the repository at this point in the history
…ation in react-spring
  • Loading branch information
awmleer committed May 31, 2022
1 parent 5120cd9 commit 44bf198
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 8 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"rc-field-form": "^1.26.6",
"react-is": "^17.0.2",
"staged-components": "^1.1.3",
"tslib": "^2.4.0"
"tslib": "^2.4.0",
"use-sync-external-store": "^1.1.0"
},
"devDependencies": {
"@babel/cli": "^7.17.10",
Expand Down Expand Up @@ -56,6 +57,7 @@
"@types/react-is": "^17.0.3",
"@types/react-virtualized": "^9.21.21",
"@types/resize-observer-browser": "^0.1.7",
"@types/use-sync-external-store": "^0.0.3",
"@typescript-eslint/eslint-plugin": "^5.26.0",
"@typescript-eslint/parser": "^5.26.0",
"babel-loader": "^8.2.5",
Expand Down
13 changes: 6 additions & 7 deletions src/components/spin-loading/spin-loading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { memo } from 'react'
import { NativeProps, withNativeProps } from '../../utils/native-props'
import { mergeProps } from '../../utils/with-default-props'
import { useSpring, animated } from '@react-spring/web'
import { isMotionReduced } from '../../utils/reduce-and-restore-motion'
import { useMotionReduced } from '../../utils/reduce-and-restore-motion'

const classPrefix = 'adm-spin-loading'

Expand All @@ -24,13 +24,12 @@ const circumference = 15 * 3.14159265358979 * 2

export const SpinLoading = memo<SpinLoadingProps>(p => {
const props = mergeProps(defaultProps, p)

const motionReduced = useMotionReduced()
const { percent } = useSpring({
loop: isMotionReduced()
? false
: {
reverse: true,
},
cancel: motionReduced,
loop: {
reverse: true,
},
from: {
percent: 80,
},
Expand Down
20 changes: 20 additions & 0 deletions src/utils/reduce-and-restore-motion.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import { Globals } from '@react-spring/web'
import { useSyncExternalStore } from 'use-sync-external-store/shim'

let reduced = false

const subscribers = new Set<() => void>()

function notify() {
subscribers.forEach(subscriber => {
subscriber()
})
}

export function reduceMotion() {
reduced = true
notify()
Globals.assign({
skipAnimation: true,
})
}

export function restoreMotion() {
reduced = false
notify()
Globals.assign({
skipAnimation: false,
})
Expand All @@ -19,3 +30,12 @@ export function restoreMotion() {
export function isMotionReduced() {
return reduced
}

export function useMotionReduced() {
return useSyncExternalStore(onStoreChange => {
subscribers.add(onStoreChange)
return () => {
subscribers.delete(onStoreChange)
}
}, isMotionReduced)
}
18 changes: 18 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3498,6 +3498,13 @@ __metadata:
languageName: node
linkType: hard

"@types/use-sync-external-store@npm:^0.0.3":
version: 0.0.3
resolution: "@types/use-sync-external-store@npm:0.0.3"
checksum: 161ddb8eec5dbe7279ac971531217e9af6b99f7783213566d2b502e2e2378ea19cf5e5ea4595039d730aa79d3d35c6567d48599f69773a02ffcff1776ec2a44e
languageName: node
linkType: hard

"@types/vinyl@npm:^2.0.4":
version: 2.0.6
resolution: "@types/vinyl@npm:2.0.6"
Expand Down Expand Up @@ -4487,6 +4494,7 @@ __metadata:
"@types/react-is": ^17.0.3
"@types/react-virtualized": ^9.21.21
"@types/resize-observer-browser": ^0.1.7
"@types/use-sync-external-store": ^0.0.3
"@typescript-eslint/eslint-plugin": ^5.26.0
"@typescript-eslint/parser": ^5.26.0
"@use-gesture/react": 10.2.15
Expand Down Expand Up @@ -4543,6 +4551,7 @@ __metadata:
ts-node: 10.8.0
tslib: ^2.4.0
typescript: ~4.6.4
use-sync-external-store: ^1.1.0
vite: ^2.9.9
webpack: ^5.72.1
webpack-bundle-analyzer: ^4.5.0
Expand Down Expand Up @@ -16600,6 +16609,15 @@ __metadata:
languageName: node
linkType: hard

"use-sync-external-store@npm:^1.1.0":
version: 1.1.0
resolution: "use-sync-external-store@npm:1.1.0"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
checksum: 8993a0b642f91d7fcdbb02b7b3ac984bd3af4769686f38291fe7fcfe73dfb73d6c64d20dfb7e5e7fbf5a6da8f5392d6f8e5b00c243a04975595946e82c02b883
languageName: node
linkType: hard

"use@npm:^3.1.0":
version: 3.1.1
resolution: "use@npm:3.1.1"
Expand Down

0 comments on commit 44bf198

Please sign in to comment.