【问题标题】:React hook useRef() variable is null on Android, but works on iOSReact hook useRef() 变量在 Android 上为 null,但在 iOS 上有效
【发布时间】:2019-09-18 18:01:20
【问题描述】:

所以我有一个组件,它被一个组件包裹,组件有一个ref:

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 内部始终为 null,有趣的是,ViewRef.current 在组件内部和tapSliderGesture 外部为 null。

下面的完整示例:

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>
  );
};

【问题讨论】:

    标签: javascript reactjs react-native react-hooks


    【解决方案1】:

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

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

    解决了...

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

    提到的另一个解决方法是向视图节点添加一个空的 onLayout 属性:onLayout={() =&gt; {}}

    【讨论】:

      猜你喜欢
      • 2022-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 2023-01-03
      相关资源
      最近更新 更多