PJT_2. Disney Application_1

리액트에서는 상태(state)가 UI를 결정하고, 이벤트는 상태만 변경하며, UI 변화는 조건부 렌더링을 통해 자동으로 따라온다


1. 상태(State) + UI 관계 이해

1.1 전체 흐름도

영화 이미지 클릭 → handleClick() → modalOpen: true + movieSelected 설정 
                                          ↓
                                   MovieModal 렌더링
                                          ↓
              X 버튼 클릭 또는 모달 외부 클릭 → setModalOpen(false) → 모달 닫힘


1.2 Row.js - 모달 상태 관리 및 이벤트 처리

const Row = ({ title, id, fetchUrl }) => {
  const [movies, setMovies] = useState([])
  const [modalOpen, setModalOpen] = useState(false);
  const [movieSelected, setMovieSelection] = useState({})

  const fetchMovieData = useCallback(async () => {
    const response = await axios.get(fetchUrl);
    // console.log('response', response);
    setMovies(response.data.results);
  }, [fetchUrl])

  useEffect(() => {
    fetchMovieData();
  }, [fetchMovieData])

  const handleClick = (movie) => {
    setModalOpen(true);
    setMovieSelection(movie);
  }

핵심 상태:

  • modalOpen: 모달 열림/닫힘 상태 (boolean)
  • movieSelected: 선택된 영화 데이터 (object)


1.3 Row.js - 영화 이미지 클릭 이벤트

              <Wrap>
                <img
                  key={movie.id}
                  src={`https://image.tmdb.org/t/p/original${movie.backdrop_path}`}
                  alt={movie.name}
                  onClick={() => handleClick(movie)}
                />
              </Wrap>
  • 이미지 클릭 시 handleClick(movie) 호출
  • 해당 영화 데이터를 movieSelected에 저장


1.4 Row.js - 조건부 모달 렌더링

      {modalOpen &&
        <MovieModal
          {...movieSelected}
          setModalOpen={setModalOpen}
        />
      }
  • modalOpen이 true일 때만 MovieModal 렌더링
  • 선택된 영화 데이터를 spread 연산자로 전달


1.5. MovieModal/index.js - 모달 컴포넌트

const MovieModal = ({
  backdrop_path,
  title,
  overview,
  name,
  release_date,
  first_air_date,
  vote_average,
  setModalOpen
}) => {

  const ref = useRef();

  useOnClickOutside(ref, () => { 
    setModalOpen(false);
  })

동작 원리:

  1. ref로 모달 DOM 요소 참조
  2. mousedown/touchstart 이벤트 리스너 등록
  3. 클릭된 요소가 ref 내부가 아니면 handler() 실행 (모달 닫기)
  4. 컴포넌트 언마운트 시 이벤트 리스너 정리 (cleanup)


Row.js => 모달 상태 관리, 영화 클릭 이벤트 처리, 조건부 렌더링

MovieModal/index.js => 모달 UI, 영화 정보 표시, 닫기 버튼

useOnClickOutside.js => 모달 외부 클릭 감지 커스텀 훅