8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

如何在 useEffect 中立即执行状态更改

user7336033 2月前

16 0

我的资产中有一堆 htm 文件。我想像书中的一页一样加载每个文件。我正在使用包含 webview 的 flashlist 来允许水平滑动。每个项目都像一整页...

我的资产中有一堆 htm 文件。我想像书中的一页一样加载每个文件。我正在使用包含 webview 的 flashlist 来允许水平滑动。每个项目就像 webview 的整个页面。

垂直滚动应由 webview 处理,水平滚动应由 flashlist 处理。我面临的问题是,在垂直滑动过程中,即使是轻微的水平滑动也会触发 flashlist 滚动到下一页。为了避免这种情况,我 scrollEnabled 使用状态变量将其设置为 false,并让 panResponder 决定仅在水平滑动显著(大于阈值)时在 useEffect 中将其设置为 true。

问题是, useEffect 在手势结束之前无法立即改变 flashlist 的 scrollEnabled 状态

有没有办法 scrollEnabled 在同步过程中强制改变 flashlist(或 flatlist)的 prop,比如 panResponder 在滑动结束之前,以便在达到 flashlist 的阈值之后处理滑动?

理想情况下,我不应该允许 flashlist 水平滚动,即使是轻微的水平滑动,但一旦水平滑动超过阈值,flashlist 将负责滚动,并且 flashlist 的漂亮动画将显示 webview 正在滑动并且下一页的 webview 即将出现。

const flashListRef = useRef(null);
const panResponderRef = useRef(null);
const insets = useSafeAreaInsets();
const [isScrollEnabled, setIsScrollEnabled] = useState(false);
const [isHorizontalScrolling, setIsHorizontalScrolling] = useState(false);

pan回应:

useEffect(() => {
  panResponderRef.current = PanResponder.create({
    onMoveShouldSetPanResponder: (_, gestureState) => {
      const { dx, dy } = gestureState;
      if (Math.abs(dy) > Math.abs(dx) || isHorizontalScrolling) {
        return false; // Vertical scroll or already scrolling horizontally, don't capture
      }
      return Math.abs(dx) > SWIPE_THRESHOLD;
    },
    onPanResponderGrant: () => {
      setIsScrollEnabled(true);
      setIsHorizontalScrolling(true);
    },
    onPanResponderRelease: () => {
      setIsHorizontalScrolling(false);
    },
  });
}, [isHorizontalScrolling]);

Flash列表:

<View
  style={[
    styles.flashListContainer,
    {
      width: dimensions.width,
      height: dimensions.height +
        (Platform.OS === 'ios'
          ? insets.top + insets.bottom
          : StatusBar.currentHeight),
      },
    ]}
  {...panResponderRef.current.panHandlers}
>
  <FlashList
    ref={flashListRef}
    data={pages}
    renderItem={renderPage}
    estimatedItemSize={dimensions.width}
    horizontal={true}
    showsHorizontalScrollIndicator={false}
    scrollEnabled={isScrollEnabled}
    // initialScrollIndex={0}
    estimatedListSize={{
      width: dimensions.width,
      height: dimensions.height,
    }}
    onMomentumScrollEnd={(event) => {
      handleMomentumScrollEnd(event);
      setIsHorizontalScrolling(false);
      setIsScrollEnabled(false);
    }}
    pagingEnabled={true}
    decelerationRate="fast"
    snapToInterval={dimensions.width}
    disableIntervalMomentum={true}
    inverted={true}
  />
</View>

我可以采用一种不太好的方式,等到滑动结束,然后 flashlist 中项目的索引突然发生变化,然后跳转到下一页。这样会使页面翻转没有动画效果。

如果没有办法解决这个问题,除了 flashlist 之外还有其他方法可以用动画实现这种行为吗?

帖子版权声明 1、本帖标题:如何在 useEffect 中立即执行状态更改
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由user7336033在本站《react-native》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 我以为滑动和手势现在已经成为一个已解决的问题,但是当我第一次开始使用 React-Native 时,通常使用 touchstart 事件来标记 ref 中潜在手势的起始位置,并计算 touchmove 期间的垂直/水平增量来确定是否向上/向下或向左/向右滑动以将其“锁定”到其中一个。

返回
作者最近主题: