How to hide React container after its been clicked?

Viewed 51

So I have an overlay flex container that when clicked adds nominations to a movie. How do I make it so that it doesn't appear and thus doesn't give the option to click it once a movie has already been nominated? The click event is located in the MovieList container where the handleNominationsClick function is being taken from props and adding it to the onClick property in the overlay.

Here is App:

    const [nominations, setNominations] = useState([]);

    const nominateMovie = (movie) => {
        const newNominationList = [...nominations, movie];
        setNominations(newNominationList);
    };

    return (
        <div className='container-fluid movie-app'>
            <div className='row d-flex align-items-center mt-4 mb-4'>
                <MovieListHeading heading='Movies' />
                <SearchBox searchValue={searchValue} setSearchValue={setSearchValue} />
            </div>
            <div className='row'>
                <MovieList
                    movies={movies}
                    nominationComponent={AddNominations}
                    handleNominationsClick={nominateMovie}
                />
            </div>
            <div className='row d-flex align-items-center mt-4 mb-4'>
                <MovieListHeading heading='Nominations' />
            </div>

MovieList Component:

onst MovieList = (props) => {
    const NominationComponent = props.nominationComponent;

    return (
        <>
            {props.movies.map((movie, index) => (
                <div className='image-container d-flex justify-content-start m-3 col-3 d-flex flex-column'>
                    <img src={movie.Poster} alt='movie'></img>
                    <div
                        onClick={() => props.handleNominationsClick(movie)}
                        className='overlay d-flex align-items-center justify-content-center'
                    >
                        <NominationComponent />
                    </div>
                </div>
            ))}
        </>
    );
};
1 Answers

I suggest storing the nominated movies in an object that provides O(1) lookup and pass the nominations as a prop to MovieList so the overlay div can be conditionally rendered. I am assuming your movies data has an id property (or some uniquely identifying property) to use. If your data doesn't have a unique identifier then I highly recommend augmenting it to include one so you can use a proper React key when mapping.

App

const [nominations, setNominations] = useState({}); // <-- object

const nominateMovie = (movie) => {
    setNominations(nominations => ({
      ...nominations,
      [movie.id]: true // <-- set movie nomination by id
    }));
};

return (
    <div className='container-fluid movie-app'>
        <div className='row d-flex align-items-center mt-4 mb-4'>
            <MovieListHeading heading='Movies' />
            <SearchBox searchValue={searchValue} setSearchValue={setSearchValue} />
        </div>
        <div className='row'>
            <MovieList
                movies={movies}
                nominationComponent={AddNominations}
                nominations={nominations} // <-- pass nominations
                handleNominationsClick={nominateMovie}
            />
        </div>

MovieList

const MovieList = (props) => {
  const NominationComponent = props.nominationComponent;

  return (
    <>
      {props.movies.map((movie, index) => (
        <div className='image-container d-flex justify-content-start m-3 col-3 d-flex flex-column'>
          <img src={movie.Poster} alt='movie'></img>
          {!props.nominations[movie.id] && ( // <-- conditional render
            <div
              onClick={() => props.handleNominationsClick(movie)}
              className='overlay d-flex align-items-center justify-content-center'
            >
              <NominationComponent />
            </div>
          )}
        </div>
      ))}
    </>
  );
};
Related