0

So i have an array.map of buttons that cycles through an array of api data. When i click this button, I want to take that specific buttons data, and store it in local storage. I am at a loss on how to do this via the googles. Any ideas?

{this.state.sb_headers.map((header, index) => (
    <Link key={index} to={header.title} className="list-group-item list-group-item-action" aria- 
    current="true" onClick={this.storeUrl}>
        <span className='icon-text'>{header.title}</span>
    </Link>
))}

So in the storeUrl function, I want to take the data from the link that was clicked and store it. As an example, lets say there are 5 items in the array that are being looped through. each one has a different URL. I want the URL that i click on.

3
  • 1
    you can do like this this.storeUrl(url). Just pass the URLs to your this.storeUrl function. Commented Sep 13, 2020 at 4:51
  • onClick={(url)=>this.storeUrl(url)} , once u do this, within the storeUrl function u can store the url in localStorage. Commented Sep 13, 2020 at 5:01
  • KSA is the closest. What worked for me was onClick={}, and adding a fat arrow function inside to pass the header.url to the function like : onClick={() => this.storeUrl(header.url)} Commented Sep 13, 2020 at 5:15

2 Answers 2

2

The easiest solution (though not the most performant) is assigning a wrapped function to the event listener.

{this.state.sb_headers.map((header, index) => (
    <Link key={index} to={header.title} className="list-group-item list-group-item-action" aria- 
    current="true" onClick={() => this.storeUrl(header)}>
        <span className='icon-text'>{header.title}</span>
    </Link>
))}

You can see I created a fat arrow function that invoked storeUrl with header as the parameter. This creates a new function for every Link on every render. Not optimal but it'll do the trick. Another way to write this is as a function that returns a function:

function storeUrl(header) {
  return function(e) {
    // This is the function that's called on click, it has access
    // to header via lexical scope
  }
}

{this.state.sb_headers.map((header, index) => (
    <Link key={index} to={header.title} className="list-group-item list-group-item-action" aria- 
    current="true" onClick={this.storeUrl(header)}>
        <span className='icon-text'>{header.title}</span>
    </Link>
))}

The final option is to attach some data to the button that can be retrieved through the click event.

{this.state.sb_headers.map((header, index) => (
    <Link key={index} to={header.title} className="list-group-item list-group-item-action" aria- 
    current="true" onClick={this.storeUrl} data-index={index}>
        <span className='icon-text'>{header.title}</span>
    </Link>
))}

// Your storeUrl method will receive e as an event
function storeUrl(e) {
  // Get more information about the click
  // The value will be a string so the + transforms it back to a number
  let index = +e.target.getAttribute('data-index');
  let header = this.state.sb_headers[index];

  // Whatever you were going to do with header
}

This solution is more performant as it doesn't create a bunch of extra wrapped functions, though the performance is can be negligible depending on the application size.

Sign up to request clarification or add additional context in comments.

Comments

1

Let's assume that each header item that you are mapping over has a property named "url".

Your onClick for the Link component would call the storeUrl method with the url parameter:

onClick={this.storeUrl(header.url)}

Then, your storeUrl method would look like this:

storeUrl(url) {
  return function() {
    // do something with url
  }
}

This is a closure and the returned function won't be invoked until the link is clicked.

2 Comments

This does not work, as it calls the function immediately on load in react if you use onClick={functionexample()}, in react, for the on click to work it needs the () to not be there.
On load storeUrl returns a function. When a link is clicked then that function gets invoked. Try it and throw a console.log inside the returned function to test it out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.