React Ref for sibling component












0















I have Component named Home which contains LeftNav, BookSearch and HomeCart Component. BookSearch Component has a input field and HomeCart component has a button. When the button in HomeCart component clicked, I need to focus the input field in BookSearch Component.



I researched a bit and I could able to only focus an element from the same Component only. How can I achieve the desired behaviour this using React Ref?



Home.jsx



class Home extends React.Component {
render() {
return (
<React.Fragment>
<div className="row no-gutters app">
<div className="col-sm-12 col-md-12 col-lg-2">
<LeftNav />
</div>
<div className="col-sm-12 col-md-12 col-lg-7 books-panel">
<BookSearch test={this.test}/>
</div>
<div className="col-sm-12 col-md-12 col-lg-3 cart-panel">
<HomeCart onClick={thi} />
</div>
</div>
</React.Fragment>
);
}
}


BookSearch.jsx



class BookSearch extends React.Component {

render() {

return (
<React.Fragment>
<button onClick={this.test}>Focus</button>
<div className="row text-center">
<div className="col-12">
<form onSubmit={this.handleSubmit}>
<h2 className="mt-5">Start searching your favorite books</h2>
<label htmlFor="search-query" className="sr-only">
Search by book name
</label>
<input
name="search-query"
onChange={this.handleChange}
type="search"
className="book-search"
value={this.state.query}
placeholder="Start searching...."
/>
<button type="submit" className="btn btn-primary btn-lg">
Search
</button>
</form>
</div>
</div>
</React.Fragment>
);
}
}


HomeCart.jsx



class HomeCart extends React.Component {

focusSearchBookInput(){
this.props.focusSearchBookInput()
}

render() {
const { cart_items } = this.props;
const cartTable = ();
const noCartItems = (
<React.Fragment>
<p>No items currently available in your cart. </p>
<button onClick={this.focusSearchBookInput} className="btn btn-success mt-5">
<ion-icon name="search" /> Start Searching
</button>
</React.Fragment>
);
return (
<React.Fragment>
<div className="row text-center">
<div className="col-12">
<h2 className="mt-5 mb-5">Books in your cart</h2>
{cart_items.length > 0 ? cartTable : noCartItems}
</div>
</div>
</React.Fragment>
);
}
}









share|improve this question























  • You have to pass a prop to handle this in a different component, and focus the input if that prop is true for example.

    – c-chavez
    Nov 20 '18 at 15:41











  • This is generally not recommended as mentioned in Exposing DOM Refs to Parent Components. So the (not recommended) react way would be to sync the focus through the Home component (which is parent to both), or the hacky way would be to convert your button to a label with the same html-for attribute that targets the input element and let the browser handle it like normal label/input combos.

    – Gabriele Petrioli
    Nov 20 '18 at 15:54
















0















I have Component named Home which contains LeftNav, BookSearch and HomeCart Component. BookSearch Component has a input field and HomeCart component has a button. When the button in HomeCart component clicked, I need to focus the input field in BookSearch Component.



I researched a bit and I could able to only focus an element from the same Component only. How can I achieve the desired behaviour this using React Ref?



Home.jsx



class Home extends React.Component {
render() {
return (
<React.Fragment>
<div className="row no-gutters app">
<div className="col-sm-12 col-md-12 col-lg-2">
<LeftNav />
</div>
<div className="col-sm-12 col-md-12 col-lg-7 books-panel">
<BookSearch test={this.test}/>
</div>
<div className="col-sm-12 col-md-12 col-lg-3 cart-panel">
<HomeCart onClick={thi} />
</div>
</div>
</React.Fragment>
);
}
}


BookSearch.jsx



class BookSearch extends React.Component {

render() {

return (
<React.Fragment>
<button onClick={this.test}>Focus</button>
<div className="row text-center">
<div className="col-12">
<form onSubmit={this.handleSubmit}>
<h2 className="mt-5">Start searching your favorite books</h2>
<label htmlFor="search-query" className="sr-only">
Search by book name
</label>
<input
name="search-query"
onChange={this.handleChange}
type="search"
className="book-search"
value={this.state.query}
placeholder="Start searching...."
/>
<button type="submit" className="btn btn-primary btn-lg">
Search
</button>
</form>
</div>
</div>
</React.Fragment>
);
}
}


HomeCart.jsx



class HomeCart extends React.Component {

focusSearchBookInput(){
this.props.focusSearchBookInput()
}

render() {
const { cart_items } = this.props;
const cartTable = ();
const noCartItems = (
<React.Fragment>
<p>No items currently available in your cart. </p>
<button onClick={this.focusSearchBookInput} className="btn btn-success mt-5">
<ion-icon name="search" /> Start Searching
</button>
</React.Fragment>
);
return (
<React.Fragment>
<div className="row text-center">
<div className="col-12">
<h2 className="mt-5 mb-5">Books in your cart</h2>
{cart_items.length > 0 ? cartTable : noCartItems}
</div>
</div>
</React.Fragment>
);
}
}









share|improve this question























  • You have to pass a prop to handle this in a different component, and focus the input if that prop is true for example.

    – c-chavez
    Nov 20 '18 at 15:41











  • This is generally not recommended as mentioned in Exposing DOM Refs to Parent Components. So the (not recommended) react way would be to sync the focus through the Home component (which is parent to both), or the hacky way would be to convert your button to a label with the same html-for attribute that targets the input element and let the browser handle it like normal label/input combos.

    – Gabriele Petrioli
    Nov 20 '18 at 15:54














0












0








0








I have Component named Home which contains LeftNav, BookSearch and HomeCart Component. BookSearch Component has a input field and HomeCart component has a button. When the button in HomeCart component clicked, I need to focus the input field in BookSearch Component.



I researched a bit and I could able to only focus an element from the same Component only. How can I achieve the desired behaviour this using React Ref?



Home.jsx



class Home extends React.Component {
render() {
return (
<React.Fragment>
<div className="row no-gutters app">
<div className="col-sm-12 col-md-12 col-lg-2">
<LeftNav />
</div>
<div className="col-sm-12 col-md-12 col-lg-7 books-panel">
<BookSearch test={this.test}/>
</div>
<div className="col-sm-12 col-md-12 col-lg-3 cart-panel">
<HomeCart onClick={thi} />
</div>
</div>
</React.Fragment>
);
}
}


BookSearch.jsx



class BookSearch extends React.Component {

render() {

return (
<React.Fragment>
<button onClick={this.test}>Focus</button>
<div className="row text-center">
<div className="col-12">
<form onSubmit={this.handleSubmit}>
<h2 className="mt-5">Start searching your favorite books</h2>
<label htmlFor="search-query" className="sr-only">
Search by book name
</label>
<input
name="search-query"
onChange={this.handleChange}
type="search"
className="book-search"
value={this.state.query}
placeholder="Start searching...."
/>
<button type="submit" className="btn btn-primary btn-lg">
Search
</button>
</form>
</div>
</div>
</React.Fragment>
);
}
}


HomeCart.jsx



class HomeCart extends React.Component {

focusSearchBookInput(){
this.props.focusSearchBookInput()
}

render() {
const { cart_items } = this.props;
const cartTable = ();
const noCartItems = (
<React.Fragment>
<p>No items currently available in your cart. </p>
<button onClick={this.focusSearchBookInput} className="btn btn-success mt-5">
<ion-icon name="search" /> Start Searching
</button>
</React.Fragment>
);
return (
<React.Fragment>
<div className="row text-center">
<div className="col-12">
<h2 className="mt-5 mb-5">Books in your cart</h2>
{cart_items.length > 0 ? cartTable : noCartItems}
</div>
</div>
</React.Fragment>
);
}
}









share|improve this question














I have Component named Home which contains LeftNav, BookSearch and HomeCart Component. BookSearch Component has a input field and HomeCart component has a button. When the button in HomeCart component clicked, I need to focus the input field in BookSearch Component.



I researched a bit and I could able to only focus an element from the same Component only. How can I achieve the desired behaviour this using React Ref?



Home.jsx



class Home extends React.Component {
render() {
return (
<React.Fragment>
<div className="row no-gutters app">
<div className="col-sm-12 col-md-12 col-lg-2">
<LeftNav />
</div>
<div className="col-sm-12 col-md-12 col-lg-7 books-panel">
<BookSearch test={this.test}/>
</div>
<div className="col-sm-12 col-md-12 col-lg-3 cart-panel">
<HomeCart onClick={thi} />
</div>
</div>
</React.Fragment>
);
}
}


BookSearch.jsx



class BookSearch extends React.Component {

render() {

return (
<React.Fragment>
<button onClick={this.test}>Focus</button>
<div className="row text-center">
<div className="col-12">
<form onSubmit={this.handleSubmit}>
<h2 className="mt-5">Start searching your favorite books</h2>
<label htmlFor="search-query" className="sr-only">
Search by book name
</label>
<input
name="search-query"
onChange={this.handleChange}
type="search"
className="book-search"
value={this.state.query}
placeholder="Start searching...."
/>
<button type="submit" className="btn btn-primary btn-lg">
Search
</button>
</form>
</div>
</div>
</React.Fragment>
);
}
}


HomeCart.jsx



class HomeCart extends React.Component {

focusSearchBookInput(){
this.props.focusSearchBookInput()
}

render() {
const { cart_items } = this.props;
const cartTable = ();
const noCartItems = (
<React.Fragment>
<p>No items currently available in your cart. </p>
<button onClick={this.focusSearchBookInput} className="btn btn-success mt-5">
<ion-icon name="search" /> Start Searching
</button>
</React.Fragment>
);
return (
<React.Fragment>
<div className="row text-center">
<div className="col-12">
<h2 className="mt-5 mb-5">Books in your cart</h2>
{cart_items.length > 0 ? cartTable : noCartItems}
</div>
</div>
</React.Fragment>
);
}
}






reactjs






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 '18 at 15:27









KalaivananKalaivanan

91




91













  • You have to pass a prop to handle this in a different component, and focus the input if that prop is true for example.

    – c-chavez
    Nov 20 '18 at 15:41











  • This is generally not recommended as mentioned in Exposing DOM Refs to Parent Components. So the (not recommended) react way would be to sync the focus through the Home component (which is parent to both), or the hacky way would be to convert your button to a label with the same html-for attribute that targets the input element and let the browser handle it like normal label/input combos.

    – Gabriele Petrioli
    Nov 20 '18 at 15:54



















  • You have to pass a prop to handle this in a different component, and focus the input if that prop is true for example.

    – c-chavez
    Nov 20 '18 at 15:41











  • This is generally not recommended as mentioned in Exposing DOM Refs to Parent Components. So the (not recommended) react way would be to sync the focus through the Home component (which is parent to both), or the hacky way would be to convert your button to a label with the same html-for attribute that targets the input element and let the browser handle it like normal label/input combos.

    – Gabriele Petrioli
    Nov 20 '18 at 15:54

















You have to pass a prop to handle this in a different component, and focus the input if that prop is true for example.

– c-chavez
Nov 20 '18 at 15:41





You have to pass a prop to handle this in a different component, and focus the input if that prop is true for example.

– c-chavez
Nov 20 '18 at 15:41













This is generally not recommended as mentioned in Exposing DOM Refs to Parent Components. So the (not recommended) react way would be to sync the focus through the Home component (which is parent to both), or the hacky way would be to convert your button to a label with the same html-for attribute that targets the input element and let the browser handle it like normal label/input combos.

– Gabriele Petrioli
Nov 20 '18 at 15:54





This is generally not recommended as mentioned in Exposing DOM Refs to Parent Components. So the (not recommended) react way would be to sync the focus through the Home component (which is parent to both), or the hacky way would be to convert your button to a label with the same html-for attribute that targets the input element and let the browser handle it like normal label/input combos.

– Gabriele Petrioli
Nov 20 '18 at 15:54












1 Answer
1






active

oldest

votes


















0














One solution could be...



Create the ref and a click handler that sets focus on the ref in Home.jsx



class Home extends React.Component {
inputRef = React.createRef();

focusHandler = () => {
this.inputRef.current.focus();
}

render() {
return (
<React.Fragment>
<div className="row no-gutters app">
<div className="col-sm-12 col-md-12 col-lg-2">
<LeftNav />
</div>
<div className="col-sm-12 col-md-12 col-lg-7 books-panel">
<BookSearch inputRef={this.inputRef} />
</div>
<div className="col-sm-12 col-md-12 col-lg-3 cart-panel">
<HomeCart focusHandler={this.focusHandler} />
</div>
</div>
</React.Fragment>
);
}
}


Add ref={this.props.inputRef} to the input in BookSearch.jsx



Add onClick={this.props.focusHandler} to the button in HomeCart.jsx






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396282%2freact-ref-for-sibling-component%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    One solution could be...



    Create the ref and a click handler that sets focus on the ref in Home.jsx



    class Home extends React.Component {
    inputRef = React.createRef();

    focusHandler = () => {
    this.inputRef.current.focus();
    }

    render() {
    return (
    <React.Fragment>
    <div className="row no-gutters app">
    <div className="col-sm-12 col-md-12 col-lg-2">
    <LeftNav />
    </div>
    <div className="col-sm-12 col-md-12 col-lg-7 books-panel">
    <BookSearch inputRef={this.inputRef} />
    </div>
    <div className="col-sm-12 col-md-12 col-lg-3 cart-panel">
    <HomeCart focusHandler={this.focusHandler} />
    </div>
    </div>
    </React.Fragment>
    );
    }
    }


    Add ref={this.props.inputRef} to the input in BookSearch.jsx



    Add onClick={this.props.focusHandler} to the button in HomeCart.jsx






    share|improve this answer




























      0














      One solution could be...



      Create the ref and a click handler that sets focus on the ref in Home.jsx



      class Home extends React.Component {
      inputRef = React.createRef();

      focusHandler = () => {
      this.inputRef.current.focus();
      }

      render() {
      return (
      <React.Fragment>
      <div className="row no-gutters app">
      <div className="col-sm-12 col-md-12 col-lg-2">
      <LeftNav />
      </div>
      <div className="col-sm-12 col-md-12 col-lg-7 books-panel">
      <BookSearch inputRef={this.inputRef} />
      </div>
      <div className="col-sm-12 col-md-12 col-lg-3 cart-panel">
      <HomeCart focusHandler={this.focusHandler} />
      </div>
      </div>
      </React.Fragment>
      );
      }
      }


      Add ref={this.props.inputRef} to the input in BookSearch.jsx



      Add onClick={this.props.focusHandler} to the button in HomeCart.jsx






      share|improve this answer


























        0












        0








        0







        One solution could be...



        Create the ref and a click handler that sets focus on the ref in Home.jsx



        class Home extends React.Component {
        inputRef = React.createRef();

        focusHandler = () => {
        this.inputRef.current.focus();
        }

        render() {
        return (
        <React.Fragment>
        <div className="row no-gutters app">
        <div className="col-sm-12 col-md-12 col-lg-2">
        <LeftNav />
        </div>
        <div className="col-sm-12 col-md-12 col-lg-7 books-panel">
        <BookSearch inputRef={this.inputRef} />
        </div>
        <div className="col-sm-12 col-md-12 col-lg-3 cart-panel">
        <HomeCart focusHandler={this.focusHandler} />
        </div>
        </div>
        </React.Fragment>
        );
        }
        }


        Add ref={this.props.inputRef} to the input in BookSearch.jsx



        Add onClick={this.props.focusHandler} to the button in HomeCart.jsx






        share|improve this answer













        One solution could be...



        Create the ref and a click handler that sets focus on the ref in Home.jsx



        class Home extends React.Component {
        inputRef = React.createRef();

        focusHandler = () => {
        this.inputRef.current.focus();
        }

        render() {
        return (
        <React.Fragment>
        <div className="row no-gutters app">
        <div className="col-sm-12 col-md-12 col-lg-2">
        <LeftNav />
        </div>
        <div className="col-sm-12 col-md-12 col-lg-7 books-panel">
        <BookSearch inputRef={this.inputRef} />
        </div>
        <div className="col-sm-12 col-md-12 col-lg-3 cart-panel">
        <HomeCart focusHandler={this.focusHandler} />
        </div>
        </div>
        </React.Fragment>
        );
        }
        }


        Add ref={this.props.inputRef} to the input in BookSearch.jsx



        Add onClick={this.props.focusHandler} to the button in HomeCart.jsx







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 '18 at 15:49









        user195257user195257

        1,04942042




        1,04942042






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396282%2freact-ref-for-sibling-component%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            Npm cannot find a required file even through it is in the searched directory

            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith