React hook useRef() 变量在 Android 上为空,但在 iOS 上有效



所以我有一个组件,它被一个组件包装,该组件有一个引用:

const viewRef = useRef(null);
...
<View ref={ viewRef }>

该组件还具有在按下时触发的功能

// locationX is the location of tapping relative to <View>
const tapSliderGesture = (locationX) => {
// we need the ViewRef to measure its size (width) and position relative to screen (px)
viewRef.current.measure((fx, fy, width, height, px) => {
const location = Math.round(((locationX - px) / width) * steps);
if (location !== state) {
setState(location);
}
});
};
...
<View ref={ viewRef } onResponderMove={ (evt) => { tapSliderGesture(evt.nativeEvent.locationX); } }>

但是,在 android 上,ViewRef.currenttapSliderGesture内部始终为空,有趣的是,ViewRef.current组件内和tapSliderGesture外部都不为空。

完整示例如下:

const AddSlider = ({setState, state, steps}) => {
const viewRef = useRef(null);
console.log('On render', viewRef.current); // prints after every re-render
// viewRef.current is not null after a render is triggered in the component
const tapSliderGesture = (locationX) => {
console.log(viewRef.current); // on iOS this prints the ref object
// on Android it prints null
viewRef.current.measure((fx, fy, width, height, px) => {
const location = Math.round(((locationX - px) / width) * steps);
if (location !== state) {
setState(location);
}
});
};
return (
<View
ref={ viewRef }
onResponderMove={ (evt) => { tapSliderGesture(evt.nativeEvent.locationX); } }
onResponderGrant={ (evt) => { tapSliderGesture(evt.nativeEvent.locationX); } }
>
<Slider .../>
</View>
);
};

所以问题是 android 有某种优化来改变 DOM 层次结构树。答案是在我的视图中添加collapsable: false道具,因此:

<View ref={ viewRef } collapsable={ false } .../>

那修复了它...

https://github.com/facebook/react-native/issues/3282

提到的另一种解决方法是向视图节点添加一个空的onLayout道具:onLayout={() => {}}

相关内容

  • 没有找到相关文章

最新更新