2

I have a small app fetching Movies. The component tree isn't very deep. I have state in App.js and it passes data to the Movies.js component. Now, Movies.js is just a container to render the ul list of Movies.

App.js passing data to Movies

<Movies
  modalData={this.state.modalData}
  toggleModal={this.openModal}
  isOpen={this.state.modalIsOpen}
  closeModal={this.closeModal}
  items={this.state.data}
  getMovieInfo={this.getMovieInfo}
  addToFavorites={this.addToFavorites}
/>

Movies.js

const Movies = props => {
   const { items, getMovieInfo, addToFavorites, isOpen, toggleModal, closeModal, modalData } = props;
   const listItems = items.map((item, id) => (
     <Movie
       key={id}
       id={id}
       imdbID={item.imdbID}
       title={item.Title}
       poster={item.Poster}
       getMovieInfo={getMovieInfo}
       addToFavorites={addToFavorites}
       imdbid={item.imdbID}
       isOpen={isOpen}
       toggleModal={toggleModal}
       closeModal={closeModal}
       modalData={modalData}
     />
   ));
   return <ul id="movie-container">{listItems}</ul>;
 };

and finally Movies.js which is just an item that is rendered in the Movie component. I tried using destructuring to keep the items prop for the Movies component because it needs that to map over and then ...props to Movie. I cant seem to make this work.

My app works fine but this is 'prop-drilling' and I think context may not be appropriate because this is not a deep tree. Higher Order Components, I don't understand yet. What can I do to make this better?

Movie.js

const Movie = props => {
  const {
    id,
    imdbID,
    title,
    poster,
    getMovieInfo,
    addToFavorites,
    isOpen,
    toggleModal,
    closeModal,
    modalData,
  } = props;
  return (
    <React.Fragment>
      <li className="movie" id={id}>
        <img srcSet={poster} alt={title} imdbid={imdbID} />
        <div className="movie-title">{title}</div>
        <div className="button-container">
          <button
            type="submit"
            className="button-small"
            onClick={toggleModal}
            imdbid={imdbID}
            title={title}
            id={id}>
            {' '}
            Info!!
          </button>
          <button
            type="submit"
            className="button-small"
            onClick={addToFavorites}
            imdbid={imdbID}
            id={id}>
            {' '}
            Fav
          </button>
        </div>
      </li>
      <Modal className="modal" selector="#modal-root" isOpen={isOpen} onClick={closeModal}>
        <div className="modal-1">
Kevin T.
  • 668
  • 3
  • 12
  • 29
  • Code snippets allow for ReactJS examples. Perhaps make a workable (or close enough) example as a snippet to demonstrate what is not working? – vol7ron Nov 12 '18 at 23:17
  • The app works fine I am asking how can I avoid the prop drilling. I am passing so many props through Movies.js, which only needs {items} and the rest go to Movie.js. – Kevin T. Nov 12 '18 at 23:21
  • I feel your comment did a much better job at describing what your after than your entire question did. Still, a working example using Stack Overflow's code snippet tool would be more ideal. – vol7ron Nov 12 '18 at 23:49
  • Regarding your comment, why not just slop it in one *movieProps* prop and pass that along, letting movieProp explode it into the necessary attributes? – vol7ron Nov 12 '18 at 23:50

1 Answers1

2

You can do like:

const Movies = ({ items, ...other}) => {

<Movie {...other} />

Or,

const { items, ...other } = props
<Movie {...other} />

Your code in example:

const Movies = ({ items, ...other}) => {
   const listItems = items.map((item, id) => (
     <Movie
       key={id}
       id={id}
       {...other}
     />
   ));
   return <ul id="movie-container">{listItems}</ul>;
 };

Your update made me afraid. You need to destructure all otherwise it will go even longer like id={other.id}. If you feel it's good rather, then do:

const { items, ...other } = props
// now when you use other props like imdbid
imdbid={other.imdbid}
Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231