Orelus
Orelus

Reputation: 1023

Children ref undefined react native

I created a component wrapper around ViewPagerAndroid (simplified version)

class TabView extends Component {

    constructor(props){
        super(props)
        this.state = { position: 0 }
    }

    changePage = (key) => { 
        this._pagerRef.setPage(key)
        this.setState({position: key})
    }

    render(){
        return(
            <ViewPagerAndroid ref={(ref) => this._pagerRef = ref}>
                 { this.props.scenes }
            </ViewPagerAndroid>
        )
    }
}

I want to trigger changePage from outside the component (eg from: <TabView ref={(ref) => this._ref = ref} />, and run this._ref.changePage(key)).

However, each time I try to do so, this._pagerRef is undefined inside the changePage function of TabView.

What am I missing ?

Upvotes: 0

Views: 1136

Answers (2)

jevakallio
jevakallio

Reputation: 35930

There is a more idiomatic React solution to the problem you are trying to solve -- namely making TabView a controlled component and setting ViewPager page on componentDidUpdate:

class TabView extends Component {
  componentDidUpdate = ({ page }) => {
    // call setPage if page has changed
    if (page !== this.props.page && this._pagerRef) {
      this._pagerRef.setPage(page);
    }
  };

  render() {
    return (
      <ViewPagerAndroid
        initialPage={this.props.page}
        ref={ref => this._pagerRef = ref}
        onPageSelected={e => this.props.pageChanged(e.nativeEvent.position)}
      >
        {this.props.scenes}
      </ViewPagerAndroid>
    );
  }
}

You can then move the current page tracking to the parent component's state and pass it down to TabView as a prop, along with a handler that updates it when the value changes:

render() {
  return (
    <TabView 
      page={this.state.page} 
      pageChanged={page => this.setState({page})}
    />
  )
}

Upvotes: 1

Pritish Vaidya
Pritish Vaidya

Reputation: 22209

You're trying to access the ref from outside of the component which has no instance to it.

Therefore you need to pass it as a prop from the parent component itself. Also you need to move the changePage to the parent component to access it from outside.

Parent

 changePage = (key) => {   //... Call the function here
    this._pagerRef.setPage(key)
    this.setState({position: key})
}

 accessRef (ref) {
     this._pagerRef = ref .  //... Bind the ref here
 } 

 <TabView passRef={this.accessRef} /> //...Pass the ref here

Child

<ViewPagerAndroid ref={this.props.passRef}> . // ... Set the ref here
                 { this.props.scenes }
            </ViewPagerAndroid>

Upvotes: 0

Related Questions