Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scrollView 组件在页面重新setState后滚动至最开始的位置 #8466

Closed
xxiizz opened this issue Jan 7, 2021 · 14 comments
Closed

scrollView 组件在页面重新setState后滚动至最开始的位置 #8466

xxiizz opened this issue Jan 7, 2021 · 14 comments
Labels
F-react Framework - React question Further information is requested T-weapp Target - 编译到微信小程序 V-3 Version - 3.x

Comments

@xxiizz
Copy link

xxiizz commented Jan 7, 2021

相关平台

微信小程序

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

复现步骤

见以下示例代码

class index extends Component {

constructor(props) {

super(props);
this.state = {
  tab: [1, 2, 3, 4, 5, 6],
  scrollIntoView: "",
  loading: false,
  list: []
};

}

render() {

return (
  <View className={style.box}>
    <ScrollView
      scrollX
      enableFlex
      scrollWithAnimation
      // scrollIntoView={this.state.scrollIntoView}
      className={style["scroll"]}
    >
      {this.state.tab.map(item => (
        <View
          key={item}
          id={`tab${item}`}
          className={style["item"]}
          onClick={() => {
            // this.setState({ scrollIntoView: `tab${item}` });
          }}
        >
          {item}
        </View>
      ))}
    </ScrollView>
    {this.state.loading ? (
      <View>加载</View>
    ) : (
      this.state.list.map(item => <View>{item}</View>)
    )}

    <View
      onClick={() => {
        this.setState({
          loading: true
        });
        // 异步加载数据
        setTimeout(() => {
          this.setState(
            { 
              loading: false,
              list: [1, 2, 3, 4, 5, 6, 7]
            }
          );
        }, 1000);
      }}
    >
      点击setState
    </View>
  </View>
);

}
}

期望结果

setState后scrollView组件的滚动位置保持不变

实际结果

setState后scrollView会滚动至最开始的位置

环境信息

� Taro v3.0.21


  Taro CLI 3.0.21 environment info:
    System:
      OS: Windows 10
    Binaries:
      Node: 12.16.1 - C:\Program Files\nodejs\node.EXE
      Yarn: 1.22.4 - ~\AppData\Roaming\npm\yarn.CMD
      npm: 6.13.4 - C:\Program Files\nodejs\npm.CMD

补充信息

最开始我以为是scrollIntoView的问题,但后面发现即使去掉scrollIntoView属性,还是会有上述问题
有点像是setState后整个组件被重新渲染了一样,但是scrollView用到的state实际并未发生变化所以理应不该重新渲染

@taro-bot2 taro-bot2 bot added F-react Framework - React T-weapp Target - 编译到微信小程序 V-3 Version - 3.x labels Jan 7, 2021
@liaojin1
Copy link

我也遇到了 请问有什么临时的解决方法吗?我是ios设置scrollIntoView没有问题,但是安卓不行 安卓每次设置scrollIntoView都会回滚到最顶部

@yuanbolin
Copy link

请问解决了吗,我也出现了这个问题

@yuanbolin
Copy link

很急,很急,这问题非常影响使用,不解决根本不敢给客户用啊

@zqjimlove
Copy link

也遇到了,难道只能回退2了?

@zqjimlove
Copy link

现在我只能用原生组件了,用了原生组件就没有问题了。其实我也奇怪我只是一个样式修改的setState,会导致全部元素的属性都刷新了。

@zqjimlove
Copy link

基于组件的 template,动态 “递归” 渲染整棵树 这可能就是问题的关键了,所有组件的状态无法保留。

@zqjimlove
Copy link

看了一下,由于是动态递归渲染的,而且在base.wxml 这个文件的 scroll-view 元素赋值了 scroll-left,如果没有设置的话就是必然是等于0的,导致每次渲染的时候都滑回最开始的地方或者 intoView 失效。

我现在都是监听事件,处理了。但是这样子的设计显然会带来更多问题。

@ZakaryCode
Copy link
Contributor

传入下 scrollTop

@ZakaryCode ZakaryCode added the question Further information is requested label May 17, 2021
@xingqiwu55555
Copy link

同样的问题,有解决的吗

@waynecz
Copy link

waynecz commented Jun 24, 2021

发现这个问题没人理

@zqjimlove
Copy link

同样的问题,有解决的吗

利用 useRef ,监听滑动事件,实时记录滑动的位置。然后 scrollLeft={scrollLeftRef.current}

@waynecz
Copy link

waynecz commented Jun 24, 2021

@zqjimlove 多谢,我去试试,不过感觉有点那啥

@ZakaryCode
Copy link
Contributor

ZakaryCode commented Jul 10, 2021

补充下该问题的代码说明,由于同级组件更新会导致 ScrollView 组件销毁,需要记录组件的实际滚动值 scrollTop 或者 scrollLeft,可以参考一下示例稍作调整。

function Demo () {
  const items = useMemo(() => {
    const temp: number[] = [];
    for (let i = 0; i < 20; i++) {
      temp.push(i);
    }
    return temp;
  }, []);

  const [show, setShow] = useState(false);
  const scrollRef = useRef(0);

  return (
    <Fragment>
      <ScrollView
        scrollWithAnimation
        scrollY
        className="scroll-view"
        scrollTop={scrollRef.current}
        onScroll={e => {
          scrollRef.current = e.detail.scrollTop
        }}
      >
        {items.map((item) => (
          <View className='item'>{`item-${item}`}</View>
        ))}
        <View className='button' onClick={() => setShow(true)}>
          点击
        </View>
      </ScrollView>
      {show && <View onClick={() => setShow(false)} className="modal"></View>}
    </Fragment>
  );
};```

@zhanshihua
Copy link

onscroll 事件的e.detail.value 在加载下一页数据的时候 就会直接变为0 这样设置依然解决不了 回到顶部的问题 怎么办

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-react Framework - React question Further information is requested T-weapp Target - 编译到微信小程序 V-3 Version - 3.x
Projects
None yet
Development

No branches or pull requests

8 participants