title: Passing ref up to parent in react
body: <p>I have a little app that has an input and based on the search value, displays weather for a particular city. I'm stuck at a certain point though. The idea is that once you search a city, it hides the text input and search button and displays some weather info and another search button to search a new city. My issue is that I want to focus on the search box once I click to search again. I hope that makes sense. I read that the ideal way to do this is with <code>refs</code>. I wired it up like such:</p>
  
  <pre><code>class WeatherForm extends React.Component {
    constructor(props) {
      super(props);
      this.city = React.createRef();
    }
  
    componentDidMount() {
      this.props.passRefUpward(this.city);
      this.city.current.focus();
    }
  
    render() {
      if (this.props.isOpen) {
        return (
          &lt;div className={style.weatherForm}&gt;
            &lt;form action='/' method='GET'&gt;
              &lt;input 
                ref={this.city} 
                onChange={this.props.updateInputValue} 
                type='text' 
                placeholder='Search city' 
              /&gt;
              &lt;input 
                onClick={e =&gt; this.props.getWeather(e)} 
                type='submit' 
                value='Search' 
              /&gt; 
            &lt;/form&gt;
          &lt;/div&gt;
        )
      } else {
        return (
          &lt;div className={style.resetButton}&gt;
            &lt;p&gt;Seach another city?&lt;/p&gt;
            &lt;button 
              onClick={this.props.resetSearch}&gt;Search
            &lt;/button&gt;
          &lt;/div&gt;
        );
      }
    }
  }
  </code></pre>
  
  <p>With this I can pass that ref up to the parent to use in my search by using <code>this.state.myRefs.current.value;</code> It works great, but when I try to reference <code>this.state.myRefs.current</code> in a different function to use <code>.focus()</code>, it returns <code>null</code>. </p>
  
  <pre><code>resetSearch = () =&gt; {
      console.log(this.state.myRefs.current); // &lt;- returns null
  
      this.setState({
        isOpen: !this.state.isOpen,
        details: [],
        video: []
      });
    }
  </code></pre>
  
  <p>Is this because I'm hiding and showing different components based on the search click? I've read numerous posts on SO, but I still can't crack this. Any help is appreciated. I'll include the full code below. To see it in full here is the git repo: <a href="https://github.com/DanDeller/tinyWeather/blob/master/src/components/WeatherMain.js" rel="nofollow noreferrer">https://github.com/DanDeller/tinyWeather/blob/master/src/components/WeatherMain.js</a></p>
  
  <pre><code>class Weather extends React.Component {
    constructor(props) {
      super(props);
  
      this.state = {
        recentCities: [],
        details: [],
        isOpen: true,
        myRefs: '',
        video: '',
        city: ''
      };
  
      this.updateInputValue = this.updateInputValue.bind(this);
      this.getRefsFromChild = this.getRefsFromChild.bind(this);
      this.resetSearch = this.resetSearch.bind(this);
      this.getWeather = this.getWeather.bind(this);
    }
  
    updateInputValue = (e) =&gt; {
      ...
    }
  
    resetSearch = () =&gt; {
      console.log(this.state.myRefs.current);
  
      this.setState({
        isOpen: !this.state.isOpen,
        details: [],
        video: []
      });
    }
  
    getWeather = (e) =&gt; {
      ...
    }
  
    getRefsFromChild = (childRefs) =&gt; {
      ...
    }
  
    render() {
      return (
        &lt;section className={style.container}&gt;
          &lt;div className={style.weatherMain + ' ' + style.bodyText}&gt;
            &lt;video key={this.state.video} className={style.video} loop autoPlay muted&gt;
              &lt;source src={this.state.video} type="video/mp4"&gt;
              &lt;/source&gt;
              Your browser does not support the video tag.
            &lt;/video&gt;
            &lt;div className={style.hold}&gt;
              &lt;div className={style.weatherLeft}&gt;
                &lt;WeatherForm
                  updateInputValue={this.updateInputValue}
                  getWeather={this.getWeather}
                  passRefUpward={this.getRefsFromChild}
                  resetSearch={this.resetSearch}
                  isOpen={this.state.isOpen}
  
                /&gt;
                &lt;WeatherList
                  details={this.state.details}
                  city={this.state.city}
                  isOpen={this.state.isOpen}
                /&gt;
              &lt;/div&gt;
              &lt;div className={style.weatherRight}&gt;
                &lt;Sidebar
                  recentCities={this.state.recentCities}
                /&gt;
              &lt;/div&gt;
              &lt;div className={style.clear}&gt;&lt;/div&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/section&gt;
      );
    }
  }
  
  
  class WeatherForm extends React.Component {
    constructor(props) {
      super(props);
      this.city = React.createRef();
    }
  
    componentDidMount() {
      this.props.passRefUpward(this.city);
      this.city.current.focus();
    }
  
    render() {
      if (this.props.isOpen) {
        return (
          &lt;div className={style.weatherForm}&gt;
            &lt;form action='/' method='GET'&gt;
              &lt;input 
                ref={this.city} 
                onChange={this.props.updateInputValue} 
                type='text' 
                placeholder='Search city' 
              /&gt;
              &lt;input 
                onClick={e =&gt; this.props.getWeather(e)} 
                type='submit' 
                value='Search' 
              /&gt; 
            &lt;/form&gt;
          &lt;/div&gt;
        )
      } else {
        return (
          &lt;div className={style.resetButton}&gt;
            &lt;p&gt;Seach another city?&lt;/p&gt;
            &lt;button 
              onClick={this.props.resetSearch}&gt;Search
            &lt;/button&gt;
          &lt;/div&gt;
        );
      }
    }
  }
  
  export default Weather;
  </code></pre>