How to attach an event handler to a dynamically created item in React












-1















I am new to React and am trying to add an onClick event handle to a list item which is created using map.



Currently, the page renders with the individual items each having their own button. However, when i click on any of the button an error



TypeError: Cannot read property 'AddThisToReadingList' of undefined.



Any help would be appreciated in understanding what is happening. Thanks in advance.



import React, {Component} from 'react';

class ResultsList extends Component{

constructor(){
super();
this.state={
currentUserEmail: 'brad.ga.co',
currentBookId: {}
}
}

AddThisToReadingList(index){
console.log('this');
//set state
//axios request to get book info
//send to node update user
}

render(){
console.log('Rendering');
return(
<div>
<ul>
<ListedBooks data ={this.props.listFromGoogle}/>
</ul>
</div>
)
}
};

const ListedBooks= props =>{
if (props.data === undefined){
return (<div>Loading....</div>)
}

return(
props.data.map( (book, index)=>{
return <li key={index}>
<h4>Title: {book.volumeInfo.title}</h4>
<div>Author: {book.volumeInfo.authors.map((element, index)=> <p key={index}>{element}</p>)}</div>
<p>Description: {book.volumeInfo.description}</p>
<p>Release Date: {book.volumeInfo.publishedDate}</p>
<img src={book.volumeInfo.imageLinks.smallThumbnail}/>
<br/>
<button onClick={()=>this.AddThisToReadingList(index)}>Add to my reading list</button>
</li>
})
)
}




export default ResultsList;









share|improve this question























  • Try <ListedBooks data={this.props.listFromGoogle} AddThisToReadingList={this.AddThisToReadingList}/> then, in your map, <button onClick={()=>props.AddThisToReadingList(index)}>. this is undefined inside ListedBooks.

    – Tex
    Nov 25 '18 at 12:08













  • you AddThisToReadingList function is in another class. What are you doing?

    – Dmitrii G.
    Nov 25 '18 at 12:10











  • I left out .bind(this) in my previous comment, but added it in my answer.

    – Tex
    Nov 25 '18 at 12:49
















-1















I am new to React and am trying to add an onClick event handle to a list item which is created using map.



Currently, the page renders with the individual items each having their own button. However, when i click on any of the button an error



TypeError: Cannot read property 'AddThisToReadingList' of undefined.



Any help would be appreciated in understanding what is happening. Thanks in advance.



import React, {Component} from 'react';

class ResultsList extends Component{

constructor(){
super();
this.state={
currentUserEmail: 'brad.ga.co',
currentBookId: {}
}
}

AddThisToReadingList(index){
console.log('this');
//set state
//axios request to get book info
//send to node update user
}

render(){
console.log('Rendering');
return(
<div>
<ul>
<ListedBooks data ={this.props.listFromGoogle}/>
</ul>
</div>
)
}
};

const ListedBooks= props =>{
if (props.data === undefined){
return (<div>Loading....</div>)
}

return(
props.data.map( (book, index)=>{
return <li key={index}>
<h4>Title: {book.volumeInfo.title}</h4>
<div>Author: {book.volumeInfo.authors.map((element, index)=> <p key={index}>{element}</p>)}</div>
<p>Description: {book.volumeInfo.description}</p>
<p>Release Date: {book.volumeInfo.publishedDate}</p>
<img src={book.volumeInfo.imageLinks.smallThumbnail}/>
<br/>
<button onClick={()=>this.AddThisToReadingList(index)}>Add to my reading list</button>
</li>
})
)
}




export default ResultsList;









share|improve this question























  • Try <ListedBooks data={this.props.listFromGoogle} AddThisToReadingList={this.AddThisToReadingList}/> then, in your map, <button onClick={()=>props.AddThisToReadingList(index)}>. this is undefined inside ListedBooks.

    – Tex
    Nov 25 '18 at 12:08













  • you AddThisToReadingList function is in another class. What are you doing?

    – Dmitrii G.
    Nov 25 '18 at 12:10











  • I left out .bind(this) in my previous comment, but added it in my answer.

    – Tex
    Nov 25 '18 at 12:49














-1












-1








-1








I am new to React and am trying to add an onClick event handle to a list item which is created using map.



Currently, the page renders with the individual items each having their own button. However, when i click on any of the button an error



TypeError: Cannot read property 'AddThisToReadingList' of undefined.



Any help would be appreciated in understanding what is happening. Thanks in advance.



import React, {Component} from 'react';

class ResultsList extends Component{

constructor(){
super();
this.state={
currentUserEmail: 'brad.ga.co',
currentBookId: {}
}
}

AddThisToReadingList(index){
console.log('this');
//set state
//axios request to get book info
//send to node update user
}

render(){
console.log('Rendering');
return(
<div>
<ul>
<ListedBooks data ={this.props.listFromGoogle}/>
</ul>
</div>
)
}
};

const ListedBooks= props =>{
if (props.data === undefined){
return (<div>Loading....</div>)
}

return(
props.data.map( (book, index)=>{
return <li key={index}>
<h4>Title: {book.volumeInfo.title}</h4>
<div>Author: {book.volumeInfo.authors.map((element, index)=> <p key={index}>{element}</p>)}</div>
<p>Description: {book.volumeInfo.description}</p>
<p>Release Date: {book.volumeInfo.publishedDate}</p>
<img src={book.volumeInfo.imageLinks.smallThumbnail}/>
<br/>
<button onClick={()=>this.AddThisToReadingList(index)}>Add to my reading list</button>
</li>
})
)
}




export default ResultsList;









share|improve this question














I am new to React and am trying to add an onClick event handle to a list item which is created using map.



Currently, the page renders with the individual items each having their own button. However, when i click on any of the button an error



TypeError: Cannot read property 'AddThisToReadingList' of undefined.



Any help would be appreciated in understanding what is happening. Thanks in advance.



import React, {Component} from 'react';

class ResultsList extends Component{

constructor(){
super();
this.state={
currentUserEmail: 'brad.ga.co',
currentBookId: {}
}
}

AddThisToReadingList(index){
console.log('this');
//set state
//axios request to get book info
//send to node update user
}

render(){
console.log('Rendering');
return(
<div>
<ul>
<ListedBooks data ={this.props.listFromGoogle}/>
</ul>
</div>
)
}
};

const ListedBooks= props =>{
if (props.data === undefined){
return (<div>Loading....</div>)
}

return(
props.data.map( (book, index)=>{
return <li key={index}>
<h4>Title: {book.volumeInfo.title}</h4>
<div>Author: {book.volumeInfo.authors.map((element, index)=> <p key={index}>{element}</p>)}</div>
<p>Description: {book.volumeInfo.description}</p>
<p>Release Date: {book.volumeInfo.publishedDate}</p>
<img src={book.volumeInfo.imageLinks.smallThumbnail}/>
<br/>
<button onClick={()=>this.AddThisToReadingList(index)}>Add to my reading list</button>
</li>
})
)
}




export default ResultsList;






reactjs






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 25 '18 at 11:48









newcasionewcasio

155




155













  • Try <ListedBooks data={this.props.listFromGoogle} AddThisToReadingList={this.AddThisToReadingList}/> then, in your map, <button onClick={()=>props.AddThisToReadingList(index)}>. this is undefined inside ListedBooks.

    – Tex
    Nov 25 '18 at 12:08













  • you AddThisToReadingList function is in another class. What are you doing?

    – Dmitrii G.
    Nov 25 '18 at 12:10











  • I left out .bind(this) in my previous comment, but added it in my answer.

    – Tex
    Nov 25 '18 at 12:49



















  • Try <ListedBooks data={this.props.listFromGoogle} AddThisToReadingList={this.AddThisToReadingList}/> then, in your map, <button onClick={()=>props.AddThisToReadingList(index)}>. this is undefined inside ListedBooks.

    – Tex
    Nov 25 '18 at 12:08













  • you AddThisToReadingList function is in another class. What are you doing?

    – Dmitrii G.
    Nov 25 '18 at 12:10











  • I left out .bind(this) in my previous comment, but added it in my answer.

    – Tex
    Nov 25 '18 at 12:49

















Try <ListedBooks data={this.props.listFromGoogle} AddThisToReadingList={this.AddThisToReadingList}/> then, in your map, <button onClick={()=>props.AddThisToReadingList(index)}>. this is undefined inside ListedBooks.

– Tex
Nov 25 '18 at 12:08







Try <ListedBooks data={this.props.listFromGoogle} AddThisToReadingList={this.AddThisToReadingList}/> then, in your map, <button onClick={()=>props.AddThisToReadingList(index)}>. this is undefined inside ListedBooks.

– Tex
Nov 25 '18 at 12:08















you AddThisToReadingList function is in another class. What are you doing?

– Dmitrii G.
Nov 25 '18 at 12:10





you AddThisToReadingList function is in another class. What are you doing?

– Dmitrii G.
Nov 25 '18 at 12:10













I left out .bind(this) in my previous comment, but added it in my answer.

– Tex
Nov 25 '18 at 12:49





I left out .bind(this) in my previous comment, but added it in my answer.

– Tex
Nov 25 '18 at 12:49












2 Answers
2






active

oldest

votes


















0














This should do the trick:



In ResultsList:



<ListedBooks
data={this.props.listFromGoogle}
AddThisToReadingList={this.AddThisToReadingList.bind(this)}
/>


In ListedBooks:



<button onClick={()=>props.AddThisToReadingList(index)}>
Add to my reading list
</button>


ListedBooks knows nothing about this in ResultsList. this is, in fact, undefined in ListedBooks. You need to pass the method to ListedBooks as a prop in order to access it there.






share|improve this answer


























  • Thankyou for the code, but more importantly the explanation Tex. Working!

    – newcasio
    Nov 25 '18 at 22:29



















-2














Add additional data to button like



<button id="additem" data-index={index}></button>


Then you can add listener with native javascript



render() {
const button = document.getElementById('additem');
button.addEventListener('click', () => {
this.AddThisToReadingList(button.dataset.index);
})

return (
props.data.map( (book, index)=>{
return <li key={index}>
<h4>Title: {book.volumeInfo.title}</h4>
<div>Author: {book.volumeInfo.authors.map((element, index)=> <p key={index}>{element}</p>)}</div>
<p>Description: {book.volumeInfo.description}</p>
<p>Release Date: {book.volumeInfo.publishedDate}</p>
<img src={book.volumeInfo.imageLinks.smallThumbnail}/>
<br/>
<button data-index={index}>Add to my reading list</button>
</li>
})
)
}





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%2f53467117%2fhow-to-attach-an-event-handler-to-a-dynamically-created-item-in-react%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    This should do the trick:



    In ResultsList:



    <ListedBooks
    data={this.props.listFromGoogle}
    AddThisToReadingList={this.AddThisToReadingList.bind(this)}
    />


    In ListedBooks:



    <button onClick={()=>props.AddThisToReadingList(index)}>
    Add to my reading list
    </button>


    ListedBooks knows nothing about this in ResultsList. this is, in fact, undefined in ListedBooks. You need to pass the method to ListedBooks as a prop in order to access it there.






    share|improve this answer


























    • Thankyou for the code, but more importantly the explanation Tex. Working!

      – newcasio
      Nov 25 '18 at 22:29
















    0














    This should do the trick:



    In ResultsList:



    <ListedBooks
    data={this.props.listFromGoogle}
    AddThisToReadingList={this.AddThisToReadingList.bind(this)}
    />


    In ListedBooks:



    <button onClick={()=>props.AddThisToReadingList(index)}>
    Add to my reading list
    </button>


    ListedBooks knows nothing about this in ResultsList. this is, in fact, undefined in ListedBooks. You need to pass the method to ListedBooks as a prop in order to access it there.






    share|improve this answer


























    • Thankyou for the code, but more importantly the explanation Tex. Working!

      – newcasio
      Nov 25 '18 at 22:29














    0












    0








    0







    This should do the trick:



    In ResultsList:



    <ListedBooks
    data={this.props.listFromGoogle}
    AddThisToReadingList={this.AddThisToReadingList.bind(this)}
    />


    In ListedBooks:



    <button onClick={()=>props.AddThisToReadingList(index)}>
    Add to my reading list
    </button>


    ListedBooks knows nothing about this in ResultsList. this is, in fact, undefined in ListedBooks. You need to pass the method to ListedBooks as a prop in order to access it there.






    share|improve this answer















    This should do the trick:



    In ResultsList:



    <ListedBooks
    data={this.props.listFromGoogle}
    AddThisToReadingList={this.AddThisToReadingList.bind(this)}
    />


    In ListedBooks:



    <button onClick={()=>props.AddThisToReadingList(index)}>
    Add to my reading list
    </button>


    ListedBooks knows nothing about this in ResultsList. this is, in fact, undefined in ListedBooks. You need to pass the method to ListedBooks as a prop in order to access it there.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 26 '18 at 9:01

























    answered Nov 25 '18 at 12:24









    TexTex

    1,6031527




    1,6031527













    • Thankyou for the code, but more importantly the explanation Tex. Working!

      – newcasio
      Nov 25 '18 at 22:29



















    • Thankyou for the code, but more importantly the explanation Tex. Working!

      – newcasio
      Nov 25 '18 at 22:29

















    Thankyou for the code, but more importantly the explanation Tex. Working!

    – newcasio
    Nov 25 '18 at 22:29





    Thankyou for the code, but more importantly the explanation Tex. Working!

    – newcasio
    Nov 25 '18 at 22:29













    -2














    Add additional data to button like



    <button id="additem" data-index={index}></button>


    Then you can add listener with native javascript



    render() {
    const button = document.getElementById('additem');
    button.addEventListener('click', () => {
    this.AddThisToReadingList(button.dataset.index);
    })

    return (
    props.data.map( (book, index)=>{
    return <li key={index}>
    <h4>Title: {book.volumeInfo.title}</h4>
    <div>Author: {book.volumeInfo.authors.map((element, index)=> <p key={index}>{element}</p>)}</div>
    <p>Description: {book.volumeInfo.description}</p>
    <p>Release Date: {book.volumeInfo.publishedDate}</p>
    <img src={book.volumeInfo.imageLinks.smallThumbnail}/>
    <br/>
    <button data-index={index}>Add to my reading list</button>
    </li>
    })
    )
    }





    share|improve this answer




























      -2














      Add additional data to button like



      <button id="additem" data-index={index}></button>


      Then you can add listener with native javascript



      render() {
      const button = document.getElementById('additem');
      button.addEventListener('click', () => {
      this.AddThisToReadingList(button.dataset.index);
      })

      return (
      props.data.map( (book, index)=>{
      return <li key={index}>
      <h4>Title: {book.volumeInfo.title}</h4>
      <div>Author: {book.volumeInfo.authors.map((element, index)=> <p key={index}>{element}</p>)}</div>
      <p>Description: {book.volumeInfo.description}</p>
      <p>Release Date: {book.volumeInfo.publishedDate}</p>
      <img src={book.volumeInfo.imageLinks.smallThumbnail}/>
      <br/>
      <button data-index={index}>Add to my reading list</button>
      </li>
      })
      )
      }





      share|improve this answer


























        -2












        -2








        -2







        Add additional data to button like



        <button id="additem" data-index={index}></button>


        Then you can add listener with native javascript



        render() {
        const button = document.getElementById('additem');
        button.addEventListener('click', () => {
        this.AddThisToReadingList(button.dataset.index);
        })

        return (
        props.data.map( (book, index)=>{
        return <li key={index}>
        <h4>Title: {book.volumeInfo.title}</h4>
        <div>Author: {book.volumeInfo.authors.map((element, index)=> <p key={index}>{element}</p>)}</div>
        <p>Description: {book.volumeInfo.description}</p>
        <p>Release Date: {book.volumeInfo.publishedDate}</p>
        <img src={book.volumeInfo.imageLinks.smallThumbnail}/>
        <br/>
        <button data-index={index}>Add to my reading list</button>
        </li>
        })
        )
        }





        share|improve this answer













        Add additional data to button like



        <button id="additem" data-index={index}></button>


        Then you can add listener with native javascript



        render() {
        const button = document.getElementById('additem');
        button.addEventListener('click', () => {
        this.AddThisToReadingList(button.dataset.index);
        })

        return (
        props.data.map( (book, index)=>{
        return <li key={index}>
        <h4>Title: {book.volumeInfo.title}</h4>
        <div>Author: {book.volumeInfo.authors.map((element, index)=> <p key={index}>{element}</p>)}</div>
        <p>Description: {book.volumeInfo.description}</p>
        <p>Release Date: {book.volumeInfo.publishedDate}</p>
        <img src={book.volumeInfo.imageLinks.smallThumbnail}/>
        <br/>
        <button data-index={index}>Add to my reading list</button>
        </li>
        })
        )
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 25 '18 at 12:11









        Ardy FebriansyahArdy Febriansyah

        317




        317






























            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%2f53467117%2fhow-to-attach-an-event-handler-to-a-dynamically-created-item-in-react%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

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)