Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

change scrollTop in reactjs

I just learn react, and want to achieve a function : both A,B are components, if A scroll, then B scroll

The following is my code

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

but actually I want my code like this

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

//...
handleScroll(){
    this.setState({scrollSeed: ++this.state.scrollSeed})
}

it is similar to 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
}

In other words, I want some attribute, like scrollTop(different form <input value={}> ,because <A scrollTop={}> doesn't work) ,is bind with some state, so that I can just use setState, and they will update by themselves.

I googled before but can't find the answser. I hope that my poor English won't confuse you.

like image 612
edeity Avatar asked Nov 17 '15 04:11

edeity


People also ask

How do I change the Scrolltop in React?

Use the window. scrollTo() method to scroll to the top of the page in React, e.g. window. scrollTo(0, 0) . The scrollTo method on the window object scrolls to a particular set of coordinates in the document.

How do you control scroll in React?

U need to set window. scrollTo(0, 0) when u click on link so it would start on top of page.

How do you scrollTo particular ID in React?

The most simple way is to use ref to store the reference of the element that you want to scroll to. And call myRef. current. scrollIntoView() to scroll it into the view.


2 Answers

There are a number of patterns to achieve this. This sample is what I came up with to get you up and going.

First create a component class which has an oversize element for scroll effect. When dragging the scroll bar, this component calls its handleScroll React property to notify its parent component, with the value of 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 );
    }
});

The parent component, aka wrapper, keeps the scroll top value in its state. Its handleScroll is passed to the child components as callback. Any scroll on the child elements triggers the callback, sets the state, results in a redraw, and updates the child component.

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

And render the wrapper, presuming an existing <div id="container"></div>.

ReactDOM.render(
    <Wrapper />,
    document.getElementById('container')
);
like image 84
Season Avatar answered Sep 20 '22 08:09

Season


2019's answer

First, the fix:

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

Second, a little explanation:

Idk what is your reason why you got here but I have used flex-direction: column-reverse for my FlatList (it's a list of elements). And I need this property for z-index purposes. However, browsers set their scroll position to the end for such elements (tables, chats, etc.) - this may be useful but I don't need that in my case.

Also, example is shown using React Hooks, but you can use older more traditional way of defining refs

like image 30
Jerry Green Avatar answered Sep 19 '22 08:09

Jerry Green