在reactjs中更改scrollTop

ede*_*ity 12 javascript reactjs

我只是学习反应,并希望实现一个功能: A,B都是组件,如果是A滚动,那么B滚动

以下是我的代码

<A onScroll="handleScroll"></A>

//what i write now
handleScroll: function(event){
    var target = event.nativeEvent.target;

    //do something to change scrollTop value
    target.scrollTop += 1;

    // it looks the same as not use react
    document.getElementById(B).scrollTop = target.scrollTop;
}
Run Code Online (Sandbox Code Playgroud)

但实际上我想要这样的代码

//what i want
<A scrollTop={this.props.scrollSeed}></A>
<B scrollTop={this.props.scrollSeed}></B>

//...
handleScroll(){
    this.setState({scrollSeed: ++this.state.scrollSeed})
}
Run Code Online (Sandbox Code Playgroud)

它类似于 input

<input value="this.props.value"/>
<input value="this.props.value"/>
<input ref='c' onChange={handleChange}>

//...
handleChange: function() {
    // enter some code in c and then render in a and b automatically
}
Run Code Online (Sandbox Code Playgroud)

换句话说,我想要一些属性,比如scrollTop(不同的形式<input value={}>,因为<A scrollTop={}>不起作用),与某种状态绑定,以便我可以使用setState,并且它们将自己更新.

我之前用Google搜索但找不到答案.我希望我可怜的英语不会让你感到困惑.

Sea*_*son 11

有许多模式可以实现这一目标.这个样本就是我提出的让你起步的样本.

首先创建一个具有超大元素的组件类,用于滚动效果.拖动滚动条时,此组件调用其handleScrollReact属性以通知其父组件,其值为scrollTop.

var Elem = React.createClass({
    render() {
        return (
            <div ref="elem"
                onScroll={ this.onScroll }
                style={{ width: "100px", height: "100px", overflow: "scroll" }}>
                <div style={{ width: "100%", height: "200%" }}>Hello!</div>
            </div>
        );
    },
    componentDidUpdate() {
        this.refs.elem.scrollTop = this.props.scrollTop;
    },
    onScroll() {
        this.props.handleScroll( this.refs.elem.scrollTop );
    }
});
Run Code Online (Sandbox Code Playgroud)

父组件(也称为包装器)将滚动顶部值保持在其状态.它handleScroll作为回调传递给子组件.子元素上的任何滚动都会触发回调,设置状态,导致重绘,并更新子组件.

var Wrapper = React.createClass({
    getInitialState() {
        return {
            scrollTop: 0
        }
    },
    render() {
        return (
            <div>
                <Elem scrollTop={ this.state.scrollTop } handleScroll={ this.handleScroll } />
                <Elem scrollTop={ this.state.scrollTop } handleScroll={ this.handleScroll } />
            </div>
        );
    },
    handleScroll( scrollTop ) {
        this.setState({ scrollTop });
    }
});
Run Code Online (Sandbox Code Playgroud)

然后渲染包装器,假设存在<div id="container"></div>.

ReactDOM.render(
    <Wrapper />,
    document.getElementById('container')
);
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的帮助!我发现不需要使用`ReactDOM.findDOMNode()`,`this.refs.elem`足够了(并且还节省了10%的CPU使用率,^ _ ^); 在此之前,我只是尝试将我的代码放在`componentWillMount`中,但它应该是`componentDidUpdate`;毕竟,再次感谢; (2认同)

Jer*_*een 8

2019的答案

首先,解决方法:

const resetScrollEffect = ({ element }) => {
  element.current.getScrollableNode().children[0].scrollTop = 0
}

const Table = props => {
  const tableRef = useRef(null)
  useEffect(() => resetScrollEffect({ element: tableRef }), [])
  return (
    <Component>
      <FlatList
        ref={someRef}
      />
    </Component>
  )
}
Run Code Online (Sandbox Code Playgroud)

二,一点解释:

flex-direction: column-reverseIdk 您到这里来的原因是什么,但是我用了FlatList(这是元素列表)。我需要此属性用于z-index目的。但是,浏览器将此类元素(表格,聊天等)的滚动位置设置为末尾-这可能很有用,但在我的情况下不需要。

此外,示例还显示了使用React Hooks的示例,但是您可以使用旧的更传统的定义引用的方式

  • @BenjaminAtkin是在react中用于useEffect时命名函数* Effect的标准。但是对应于该问题的主线是`element.current.getScrollableNode()。children [0] .scrollTop =`,因为上述答案中的`element.current.scrollTop =`不适用于我(它在一些旧时代) (2认同)

Luk*_*kas 6

this.refs 已弃用。使用 reactjs.org/docs/refs-and-the-dom.html#creating-refs

import React from 'react';

class SomeComponent extends React.Component {
  constructor(props) {
    super(props);
    this.resultsDiv = React.createRef();
  }

  someFunction(){
     this.resultsDiv.current.scrollIntoView({behavior: 'smooth'});

     // alternative:
     // this.resultsDiv.current.scrollTop = 0;
  }

  render() {
    return (
      <div ref={this.resultsDiv} />
    );
  }
}

export default SomeComponent;


Run Code Online (Sandbox Code Playgroud)