0

I have list items with very similar onClick functionality on each and I'm not sure how to avoid repeating myself. I believe I could somehow use a map but I'm struggling to think of the solution for it. Any suggestions, please?

          <li
            onClick={() => {
              setSortTitle("Release Date");
              setIsActive(false);
              dispatch(sortByReleaseDate(searchedMovies));
            }}
          >
            <a href="#">Release Date</a>
          </li>
          <li
            onClick={() => {
              setSortTitle("Rating");
              setIsActive(false);
              dispatch(sortByRating(searchedMovies));
            }}
          >
            <a href="#">Rating</a>
          </li>
          <li
            onClick={() => {
              setSortTitle("Run Time");
              setIsActive(false);
              dispatch(sortByRuntime(searchedMovies));
            }}
          >
            <a href="#">Run Time</a>
          </li>
          <li
            onClick={() => {
              setSortTitle("Title");
              setIsActive(false);
              dispatch(sortByTitle(searchedMovies));
            }}
          >

4 Answers 4

2

I would create an array of links that contains the information needed to create a link (and is also easy to add to!). Then utilising map() you can render each link and utilise a generic linkClicked function to then action the dispatch with the relevant search function.

const links = [
    { label: 'Release Date', sortFn: sortByReleaseDate },
    { label: 'Rating', sortFn: sortByRating },
    { label: 'Run Time', sortFn: sortByRuntime },
    { label: 'Title', sortFn: sortByTitle }
]

const linkClicked = (link) => {
    setSortTitle(link.label);
    setIsActive(false);
    dispatch(link.sortFn(searchedMovies));
}

return links.map(link => (
    <li onClick={() => linkClicked(link)}>
        <a href="#">{link.label}</a>
    </li>
))

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

Comments

1

You can have a titles array along with a single onItemClick(title) event handler and also a more generic sortBy action creator where you can take title as another argument or even combine {title,searchMovies} into single object (upto you):-

const titles = ["Release Date","Rating","Run Time"]

const onItemClick=(title) => {
          setSortTitle(title);
          setIsActive(false);
          dispatch(sortBy(title,searchedMovies));
        }

{titles.map(title=>
 (<li onClick={() => onItemClick(title)}>
  <a href="#">{title}</a>
</li>)
)}

Comments

1

You can use map method:

const onListItemClick = (title) => {
    setSortTitle(title);
    setIsActive(false);
    dispatch(sortByReleaseDate(searchedMovies)); 
} 

const LI = () => LiObject.map((item) => (
  <li
    onClick={e => onListItemClick(item.title, e)}
  >
    <a href="#">{item.label}</a>
  </li>
));

Comments

0

you can extract the function with a input param

        const onListItemClick=(title) => {
          setSortTitle(title);
          setIsActive(false);
          dispatch(sortByReleaseDate(searchedMovies));
        }

and invoke it using bind in the onClick handler

  <li
    onClick={onListItemClick.bind(this, "Release Date")}
  >
    <a href="#">Release Date</a>
  </li>

Another suggestion would be to grab the title from the synthetic event.

E.g.

       const onListItemClick=(e) => {
          const title=e.target.innerHTML; 
          console.log(title);
          setSortTitle(title);
          setIsActive(false);
          dispatch(sortByReleaseDate(searchedMovies));
        }

html

      <li
        onClick={onListItemClick}
      >
        <a href="#">Release Date</a>
      </li>
      <li
        onClick={onListItemClick}
      >
        <a href="#">Rating</a>
      </li>
      <li
        onClick={onListItemClick}
      >
        <a href="#">Run Time</a>
      </li>

Comments

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.