taro 无法正确获取 VirtualWaterfall 组件实例

ego6inou  于 3个月前  发布在  其他
关注(0)|答案(5)|浏览(94)

相关平台

微信小程序

小程序基础库: 3.1.1
使用框架: React

复现步骤

我使用的函数式组件,在官网 VirtualWaterfall 的示例中直接拷贝的内容

import { createRef, memo, useEffect, useLayoutEffect } from 'react';

import { View } from '@tarojs/components';
import { VirtualWaterfall, VirtualWaterfallProps } from '@tarojs/components-advanced';

import { useLoad, useReady } from '@tarojs/taro';

import './index.scss';

function buildData(offset = 0) {
  return Array(100)
    .fill(0)
    .map((_, i) => i   offset);
}

const Row = memo(({ id, index, data }: { id: string; data: any[]; index: number }) => {
  return (
    <>
      <View id={id}>{data[index]}</View>
    </>
  );
});

export default function Schedule() {
  const waterfallRef = createRef();
  useLoad(() => {
    console.log(waterfallRef, 'waterfallRef');
  });

  useReady(() => {
    console.log(waterfallRef, 'waterfallRef');
  });

  useEffect(() => {
    console.log(waterfallRef, 'waterfallRef');
  }, [waterfallRef]);

  useLayoutEffect(() => {
    console.log(waterfallRef, 'waterfallRef');
  });

  const data = buildData(0);

  function onScroll(event: VirtualWaterfallProps.IVirtualWaterfallEvent) {}

  return (
    <>
      <VirtualWaterfall
        column={7} /* 列表的列数 */
        height={300} /* 列表的高度 */
        width="100%" /* 列表的宽度 */
        item={Row} /* 列表单项组件,这里只能传入一个组件 */
        itemData={data} /* 渲染列表的数据 */
        itemCount={data.length} /* 渲染列表的长度 */
        itemSize={100} /* 列表单项的高度  */
        onScroll={event => {
          onScroll(event);
        }}
      />
    </>
  );
}

期望结果

我希望正确获取到 VirtualWaterfall 实例

实际结果

实际返回的是 null

环境信息

👽 Taro v3.6.17

  Taro CLI 3.6.17 environment info:
    System:
      OS: macOS 13.5.1
      Shell: 5.9 - /bin/zsh
    Binaries:
      Node: 18.12.0 - /usr/local/bin/node
      Yarn: 1.22.19 - /usr/local/bin/yarn
      npm: 8.19.2 - /usr/local/bin/npm
    npmPackages:
      @tarojs/cli: 3.6.17 => 3.6.17 
      @tarojs/components: 3.6.17 => 3.6.17 
      @tarojs/helper: 3.6.17 => 3.6.17 
      @tarojs/plugin-framework-react: 3.6.17 => 3.6.17 
      @tarojs/plugin-platform-alipay: 3.6.17 => 3.6.17 
      @tarojs/plugin-platform-h5: 3.6.17 => 3.6.17 
      @tarojs/plugin-platform-jd: 3.6.17 => 3.6.17 
      @tarojs/plugin-platform-qq: 3.6.17 => 3.6.17 
      @tarojs/plugin-platform-swan: 3.6.17 => 3.6.17 
      @tarojs/plugin-platform-tt: 3.6.17 => 3.6.17 
      @tarojs/plugin-platform-weapp: 3.6.17 => 3.6.17 
      @tarojs/react: 3.6.17 => 3.6.17 
      @tarojs/runtime: 3.6.17 => 3.6.17 
      @tarojs/shared: 3.6.17 => 3.6.17 
      @tarojs/taro: 3.6.17 => 3.6.17 
      @tarojs/taro-loader: 3.6.17 => 3.6.17 
      @tarojs/webpack5-runner: 3.6.17 => 3.6.17 
      babel-preset-taro: 3.6.17 => 3.6.17 
      eslint-config-taro: 3.6.17 => 3.6.17 
      react: ^18.0.0 => 18.2.0 
    npmGlobalPackages:
      typescript: 4.2.4
piah890a

piah890a1#

该示例也没有传入 ref 给组件用于透传啊

cnjp1d6j

cnjp1d6j2#

okok,大佬还有个问题

import { View, Text } from '@tarojs/components';
import { VirtualWaterfall, VirtualWaterfallProps } from '@tarojs/components-advanced';
import { useLoad, useReady } from '@tarojs/taro';
import { memo, useEffect, useLayoutEffect, useRef } from 'react';

import './index.scss';

function buildData(offset = 0) {
  return Array(1000)
    .fill(0)
    .map((_, i) => i + offset);
}

const Row = memo(({ id, index, data }: { id: string; data: any[]; index: number }) => {
  return (
    <View className="" id={id}>
      <Text>{data[index]}</Text>
    </View>
  );
});

export default function Schedule() {
  // 注意的是,函数式组件是无法通过 ref 拿到组件实例的
  const waterfallRef = useRef<VirtualWaterfall>(null);
  // const [data, setData] = useState(buildData(0));
  const data = buildData(0);

  useLoad(() => {
    console.log(waterfallRef, 'waterfallRef');
    // waterfallRef.current?.scrollToItem(50, 'start');
  });

  useReady(() => {
    console.log(waterfallRef, 'waterfallRef');
  });

  useEffect(() => {
    console.log(waterfallRef, 'waterfallRef');
  }, [waterfallRef]);

  useLayoutEffect(() => {
    console.log(waterfallRef, 'waterfallRef');
  });

  function onScroll(event: VirtualWaterfallProps.IVirtualWaterfallEvent) {
    console.log(event, 'event');
  }
  return (
    <>
      <VirtualWaterfall
        ref={waterfallRef}
        column={7} /* 列表的列数 */
        height={300} /* 列表的高度 */
        width="100%" /* 列表的宽度 */
        item={Row} /* 列表单项组件,这里只能传入一个组件 */
        itemData={data} /* 渲染列表的数据 */
        itemCount={data.length} /* 渲染列表的长度 */
        itemSize={60} /* 列表单项的高度  */
        initialScrollOffset={500}
        enhanced
        onScroll={event => {
          onScroll(event);
        }}
      />
    </>
  );
}

我加了initialScrollOffset 但是无法生效。我的需求就是,在初始化的时候可以直接滚动到我想要的位置,如果通过scrollTo方法,它会有一个过渡效果,我希望的是立刻滚动过去 @ZakaryCode

sbtkgmzw

sbtkgmzw3#

如果通过scrollTo方法,它会有一个过渡效果,我希望的是立刻滚动过去

public scrollTo(scrollOffset: number, enhanced?: boolean): void

这个方法有两个参数,enhanced 模式下默认有动画,可以自行禁用

3b6akqbq

3b6akqbq4#

这个我试过了,加了 false 之后,它就不能滚动了,你可以打开我的代码,把那个scrollToItem 的注释解开。并且为什么我设置 initialScrollOffset 也没有反应呢,还有什么别的方式嘛,太奇怪了

emeijp43

emeijp435#

return getScrollViewContextNode(
      `${ref.current.props.queryPrefix}#${ref.current.preset.id}`,
    ).then((node: any) => node.scrollTo(option))

核心代码就这一行,从 ref 中拿到组件实例,然后自己写一个 scrollTo 去掉动画就行了。

相关问题