Home > Net >  How to render a button in parent component based on children action in react js?
How to render a button in parent component based on children action in react js?

Time:11-24

I have a list of movie cards when a user clicks on them, they become selected and the id of each movie card is transferred to an array named "selectedList".

I want to add a "let's go" button below the movie card but conditionally. I mean when the array is empty the button should not be displayed and when the user clicked on at least a movie the button displays. the array should be checked each time and whenever it becomes equal to zero the button should disappear. the thing is all the movie cards are the children of this page and I want to render the parent component based on children's behavior.

MY MAIN PAGE:

    export default function Index(data) {
      const info = data.data.body.result;
      const selectedList = [];
    
      return (
        <>
          <main className={parentstyle.main_container}>
            <NavBar />
            <div className={style.searchbar_container}>
              <SearchBar />
            </div>
            <div className={style.card_container}>
              {info.map((movie, i) => {
                return (
                  <MovieCard
                    movieName={movie.name}
                    key={i}
                    movieId={movie._id}
                    selected={selectedList}
                    isSelected={false}
                  />
                );
              })}
            </div>
          </main>
          <button className={style.done}>Let's go!</button>
        </>
      );
    }



**MOVIE CARD COMPONENT:**

export default function Index({ selected, movieName, movieId, visibility }) {
  const [isActive, setActive] = useState(false);

  const toggleClass = () => {
    setActive(!isActive);
  };

  const pushToSelected = (e) => {
    if (selected.includes(e.target.id)) {
      selected.splice(selected.indexOf(e.target.id), 1);
      console.log(selected);
    } else {
      selected.push(e.target.id);
      console.log(selected);
    }
    toggleClass();
  };

  return (
    <div>
      <img
        className={isActive ? style.movie_selected : style.movie}
        src={`images/movies/${movieName}.jpg`}
        alt={movieName}
        id={movieId}
        onClick={pushToSelected}
      />
      <h3 className={style.title}>{movieName}</h3>
    </div>
  );
}

CodePudding user response:

You can use conditional rendering for that:

{selectedList.length > 0 && <button className={style.done}>Let's go!</button>}

Plus, you should change your selectedList to a state, and manage the update via the setSelectedList function:

import { useState } from 'react';

export default function Index(data) {
      const info = data.data.body.result;
      const [selectedList, setSelectedList] = useState([]);

Add the method to the MovieCard as a property:

<MovieCard
  movieName={movie.name}
  key={i}
  movieId={movie._id}
  selected={selectedList}
  setSelected={setSelectedList}
  isSelected={false}
/>;

And update the list in the pushToSelected method:

export default function MovieCard({ 
  selected, 
  setSelected, 
  movieName, 
  movieId, 
  visibility 
}) {
  const pushToSelected = (e) => {
    if (selected.includes(e.target.id)) {
      selected.splice(selected.indexOf(e.target.id), 1);
      console.log(selected);
    } else {
      selected.push(e.target.id);
      console.log(selected);
    }
    setSelected([...selected]);
    toggleClass();
  };
  • Related