1

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.

Arthur Ávila
  • 25
  • 2
  • 6
  • Can you please have a look at the answer here https://stackoverflow.com/a/56065152/8031495 You can make some changes and can achieve the desired solution. – snehal agrawal May 09 '19 at 18:09

1 Answers1

3

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>
        )
    }
}
MPN7
  • 1,112
  • 1
  • 10
  • 13
  • It looks a very good way to go. I guess one issue I'm missing is with width and height. I've got "this.setState is not a function. (In 'this.setState({ x, y })', 'this.setState' is undefined ) – Arthur Ávila Feb 28 '19 at 17:02
  • I forgot to create the state, see edit. What's the issue about width and height? – MPN7 Feb 28 '19 at 17:10
  • Yeah, even with the state the issue persisted. I've tried with callParentFunction = (x, y) => { this.setState({ x, y }); } Which worked – Arthur Ávila Feb 28 '19 at 17:16
  • Now when I press I get "undefined is not an object (evaluating 'this.ScrollView.scrollTo')" Almost there I guess =) – Arthur Ávila Feb 28 '19 at 17:17
  • See edit, that should work, the reason was probably `this` was not in scope of `goToComponent5` – MPN7 Feb 28 '19 at 17:38
  • I was just reading that! That I probably need to bind the context. Now it is working. Thank you very much! – Arthur Ávila Feb 28 '19 at 17:47
  • Vice-versa is possible.? I want to call Component5 method from Parent – vicky keshri Mar 18 '20 at 16:43
  • @vickykeshri I'm not sure I understood but if you use refs your parent can have acess to all variables in component 5. – MPN7 Mar 20 '20 at 09:15
  • I tried with that, seems like we can use ref only for parent component. However renderMethod are not holding ref. – vicky keshri Mar 21 '20 at 07:53
  • @vickykeshri What method are you trying to call? – MPN7 Mar 23 '20 at 09:16