Khurshid Ansari
Khurshid Ansari

Reputation: 5075

How to prevent automatic scroll to top when rerender component?

I am facing one issue in react native with nativebase.

<Content> 
   <List> 
     <ListItem> 
      <Left style={{ flex: 0 }}>
         <Icon name="user" type="SimpleLineIcons"></Icon>
      </Left>
      <Body>
         <Text> Profile </Text>
      </Body>
      <Right>
         <Switch value={this.state.profile} />
      </Right>
     </ListItem>
     ....
   </List> 
</Content> 

When i update state(rerender component) list automatically scroll to top/first :

this.setState({profile: true });

How to prevent autoscroll for better user experience?

Upvotes: 5

Views: 6674

Answers (3)

Jeff
Jeff

Reputation: 37

I've worked around this issue just by passing the y offset from the scrollview to the parent using the following. By using this.offsetY, an update to the value won't cause a re-render, but it will be passed to the child component when you need it:

In your parent component:

setScrollOffset = (y) => (this.offsetY = y);

return (
  <MyChildComponent
     data={yourData}
     setScrollOffset={this.setScrollOffset}
     yOffset={this.offsetY}>
  </MyChildComponent>
);

In your child component:

onScrollEndDrag = ({
  nativeEvent: {
    targetContentOffset: {y},
  },
}) => {
  this.props.setScrollOffset(y);
};

...

render() {
  return (
    <ScrollView
      contentOffset={{
        x: 0,
        y: this.props.yOffset !== undefined ? this.props.yOffset : 0,
      }}
      contentContainerStyle={styles.scrollViewContent}
      onScrollEndDrag={this.onScrollEndDrag}>
      ...
    </ScrollView>
  )
}

I should add that if you wish for to reset the yOffset to 0 (start at the top of the ScrollView) then you should reset that somewhere else in your parent component if a specific state change occurs.

Upvotes: 1

Khurshid Ansari
Khurshid Ansari

Reputation: 5075

I created functional list component and render in drawer. In drawer there text and switch component.

My list component was inside renderer method so whenever i toggle switch render method fire and list autocamatilly go to up.

Now, I put list component out of render method. This resolve my issue.

Thanks all guys for your quick response and suggestion.

Example :

render(){
const drawerContent = ()=>(
<Content> 
 <List> 
  <Switch value={this.state.flag) />
 </List>
</Content> 
)
return(
<Drawer content={drawerContent}>
 <Container> 
  ....
 </Container> 
</Drawer>
)
}

To

drawerContent = ()=>(
<Content> 
 <List> 
   <Switch value={this.state.flag) />
 </List>
</Content> 
)
render(){
return(
<Drawer content={this.drawerContent}>
 <Container> 
  ....
 </Container> 
</Drawer>
)
}

Upvotes: 0

Maycon Mesquita
Maycon Mesquita

Reputation: 4600

Please try this prop inside <Content> component:

<Content enableResetScrollToCoords={false} />

You can try this solution too:

handleScroll(event) {
    this.setState({ scrollY: event.nativeEvent.contentOffset.y });
}

render() {
    if (this.contentRef) {
      if (this.contentRef._scrollview) {
        this.contentRef._scrollview.resetScrollToCoords({ x: 0, y: this.state.scrollY });
      }
    }

    return (
        <Content
          ref={(c) => this.contentRef = c}
          onScroll={event => this.handleScroll(event)}
        >
    );
}

Upvotes: 2

Related Questions