Search code examples
javascriptreactjsreact-nativecomponentsscrollview

React Native ScrollView - How to scroll to a child component from another child component button?


I have this structure with a ScrollView, which is a parent with 5 childs

Parent Component with ScrollView

  • Component1
  • Component2
  • Component3
  • Component4
  • Component5

Inside Component3 I have a button that when pressed should scroll parent component ScrollView to Component5

Something like this

Home (Parent)

export default class Home extends React.Component {      
    renderComments() {
        return this.state.dataSource.map(item =>
            <CommentDetail key={item.id} comment={item} />
        );
    }

    render() {
        return (
            <ScrollView>      
                <Component1 />
                <Component2 />
                <CentralElements  {...this.state.dataSource} scroll = {this.props.scroll} />
                <Component4 />                  
                <View>
                    {this.renderComments()}
                </View>
            </ScrollView>
        );
    }
}

CentralElements (Component3)

export default class CentralElements extends React.Component {
    constructor(props) {
        super(props);
    }
  
    goToComments= () => {
        this.props.scroll.scrollTo({x: ?, y: ?, animated: true});
     };

    render() {
        return (
            <ScrollView horizontal={true}>
                <TouchableOpacity onPress={this.goToComments}>
                    <Image source={require('../../assets/image.png')} />
                    <Text>Comments</Text>
                </TouchableOpacity>
                ...
                </TouchableOpacity>
            </ScrollView>
        );
    }
};

And the Comments are the Component5, any idea on how to the parent scroll? I trying to figure what I'm missing, since thats my first contact with this.


Solution

  • What i did was..
    in component5 I call onLayout in the main view and then save x and y in the parent component. To scroll to it in component 3 on click i call the parent function that uses the scrollview ref to scroll to the values stored before

    Component5

        export default class Component5 extends Component {
    
        saveLayout() {
            this.view.measureInWindow((x, y, width, height) => {
                this.props.callParentFunction(x, y)
            })
        }
        render() {
            return (
                <View ref={ref => this.view = ref} onLayout={() => this.saveLayout()}>
    
                </View>
            )
        }
    }
    

    Component3

    export default class Component3 extends Component {
    
        render() {
            return (
                <View >
                    <TouchableOpacity onPress={()=>{this.props.goToComponent5()}}>
    
                    </TouchableOpacity>
                </View>
            )
        }
    }
    

    Parent:

    export default class Parent extends Component {
    constructor(props) {
    this.goToComponent5=this.goToComponent5.bind(this)
        super(props)
        this.state = {
            x:0,
            y:0,
        }
    }
    
        callParentFunction(x, y) {
            this.setState({ x, y })
        }
    
        goToComponent5(){
            this.ScrollView.scrollTo({x: this.state.x, y: this.state.y, animated: true});
        }
    
        render() {
            return (
                <View >
                    <ScrollView ref={ref => this.ScrollView = ref}>
                        <Component1 />
                        <Component2 />
                        <Component3 goToComponent5={this.goToComponent5}/>
                        <Component4 />
                        <Component5 callParentFunction={this.callParentFunction}/>
                    </ScrollView>
                </View>
            )
        }
    }