PanResponder onMoveShouldSetPanResponder delta not reset
オープン
まだ誰も着手していません。
API: PanResponder
Issue: Author Provided Repro
Needs: Attention
Newer Patch Available
- 主要言語
- C++
- スター
- 127k
- フォーク
- 25.3k
- 平均マージ
- 1日 23時間
- マージ済み PR(30日)
- 4
説明
Description
Delta is not reset between gestures when it returned false
PanResponder.create({
onMoveShouldSetPanResponder(e, gesture) {
const {dx, dy} = gesture
return false
},
})
That seems to be because none of the other callbacks are called and the inner state initial position isn't reset.
I'm currently fixing this with
function PanProvider({children}) {
const capturedPositionRef = useRef(null);
return <View onMoveShouldSetResponderCapture={({nativeEvent:{pageX, pageY}}) => {
// don't do anything, just capture the initial position
capturedPositionRef.current = {pageX, pageY}
return false
}}>
<PanContext.Provider value={capturedPositionRef}>{children}</PanContext.Provider>
</View>
}
export default function usePanResponderLock(direction: 'horizontal' | 'vertical') {
// uses the provider initial position
const captureGestureRef = usePanResponder();
return useRef(
PanResponder.create({
onMoveShouldSetPanResponder({ nativeEvent: { pageX, pageY } }) {
if (captureGestureRef.current) {
const { pageX: startX, pageY: startY } = captureGestureRef.current;
const dx = Math.abs(pageX - startX);
const dy = Math.abs(pageY - startY);
const dragging = dx > 2 || dy > 2;
if (!dragging) return false;
return direction === 'horizontal' ? dx > dy : dy > dx;
}
return false;
},
onPanResponderTerminationRequest() {
return true;
},
}),
).current;
}
This is working well, but the delta should be fixed in RN
Steps to reproduce
Try looking for a horizontal gesture with dx > dy:
- from the top left corner, make a vertical gesture => delta's are correct, view is not a responder.
- make a new horizontal gesture from bottom left corner => delta y is the distance with the previous touch and delta x too =>
dy > dxeven though it's a horizontal gesture
React Native Version
0.73.8
Affected Platforms
Runtime - Android
Output of npx react-native info
System:
OS: macOS 14.5
CPU: (12) arm64 Apple M2 Max
Memory: 277.72 MB / 32.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 20.9.0
path: ~/.nvm/versions/node/v20.9.0/bin/node
Yarn:
version: 1.22.19
path: /usr/local/bin/yarn
npm:
version: 10.1.0
path: ~/.nvm/versions/node/v20.9.0/bin/npm
Watchman:
version: 2024.01.22.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.13.0
path: /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 23.4
- iOS 17.4
- macOS 14.4
- tvOS 17.4
- visionOS 1.1
- watchOS 10.4
Android SDK: Not Found
IDEs:
Android Studio: 2022.3 AI-223.8836.35.2231.10811636
Xcode:
version: 15.3/15E204a
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.11
path: /usr/bin/javac
Ruby:
version: 3.3.0
path: /Users/gregoirevda/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli": Not Found
react: Not Found
react-native: Not Found
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: Not found
newArchEnabled: Not found
iOS:
hermesEnabled: Not found
newArchEnabled: Not found
Stacktrace or Logs
No stacktrace error.
Reproducer
https://snack.expo.dev/@gregoirevda/bad-orange-popsicle
Screenshots and Videos
No response
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
リンクされた Snack の再現コードと PanResponder.create/onMoveShouldSetPanResponder のパスから始め、callback が false を返したときにジェスチャーの差分がどのように初期化され、保持されるかを、Android に重点を置いて追跡します。前のジェスチャーが responder にならなかった場合でも、新しいジェスチャーが自身の開始時点からの差分を報告し、再現コードの動作が修正されれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- javascript, react-native
- 領域
- mobile
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 35/100