javascript 在不刷新页面的情况下删除任何卡片后,卡片列表不会改变

o7jaxewo  于 2023-05-21  发布在  Java
关注(0)|答案(1)|浏览(106)

我有显示用户保存的电影列表的页面。用户可以删除他保存的电影。按下按钮删除电影从服务器,并应删除卡从列表中,但在我的情况下,它消失从列表中只有刷新页面后。该项目基于React.js。 我有几个组件:应用程序,保存的电影,MoviesCardList,MoviesCard:- 应用程序是主要组件-SavedMovies -显示用户保存的电影的组件-MoviesCardList -带卡片的部分-MoviesCard - movie-card 我不明白为什么保存的电影在删除后不更新而不刷新。Detele fetch工作正常。以下是组件的组成部分:

function App() {
  const [currentUser, setCurrentUser] = useState({});
  const [isLoggedIn, setIsLoggedIn] = useState(localStorage.getItem('token') ? true : false);
  const [savedMovies, setSavedMovies] = useState([]);

  React.useEffect(() => {
    if (isLoggedIn) {
      Promise.all([mainApi.getUserInfo(), mainApi.getSavedMovies()])
        .then(([data, items]) => {
          const saved = items.filter((m) => m.owner === data._id);

          setCurrentUser(data);
          setSavedMovies(saved);
        })
        .catch((err) => {
          console.log(err);
        })
    }
  }, [isLoggedIn])

  function handleDeleteMovie(movie) {
    const savedMovie = savedMovies.find((m) => {
      return m.movieId === (movie.id || movie.movieId)
    })
    const newSavedMovies = savedMovies.filter((m) => m.movieId !== movie.id)

    mainApi.deleteMovie(savedMovie._id)
      .then(() => {
        setSavedMovies(newSavedMovies);
      })
      .catch((err) => {
        console.log(err);
      })
  }
  return (
    <div className="app">
      <CurrentUserContext.Provider value={currentUser}>
        <Routes>
          <Route path="saved-movies" element={
            <ProtectedRoute isLoggedIn={isLoggedIn}>
              <Header isLoggedIn={isLoggedIn} />
              <SavedMovies
                savedMovies={savedMovies}
                onDeleteMovie={handleDeleteMovie}
              />
              <Footer />
            </ProtectedRoute>
          } />
        </Routes>
      </CurrentUserContext.Provider>
    </div>
  );
}

function SavedMovies({ savedMovies, onDeleteMovie }) {
  const [isShortChecked, setIsShortChecked] = useState(false);
  const [initialMovies, setInitialMovies] = useState(savedMovies);
  const [searchResult, setSearchResult] = useState(initialMovies);

  function filterShortMovies(movies) {
    return movies.filter((movie) =>
      movie.duration <= 40
    )
  }

  function handleFilter(query) {
    const result = savedMovies.filter((movie) => {
      return (
        movie.nameRU.toLowerCase().includes(query.toLowerCase()) ||
        movie.nameEN.toLowerCase().includes(query.toLowerCase())
      )
    })
    setInitialMovies(result);
    setSearchResult(isShortChecked ? filterShortMovies(result) : result);
  }

  function handleShort() {
    setIsShortChecked(!isShortChecked);
    if (!isShortChecked) {
      setSearchResult(filterShortMovies(initialMovies))
    } else {
      setSearchResult(initialMovies)
    }
  }

  function onSearchSubmit(inputData) {
    handleFilter(inputData)
  }

  useEffect(() => {
    setSearchResult(savedMovies)
  }, [savedMovies])

  return (
    <div className='saved-movies'>
      <SearchForm
        onSearch={onSearchSubmit}
        isShort={isShortChecked}
        handleShort={handleShort} />
      <MoviesCardList
        savedMovies={savedMovies}
        onDeleteMovie={onDeleteMovie}
        movies={searchResult}
      />
    </div>
  )
}

function MoviesCard({ movie, onSaveMovie, onDeleteMovie, isSaved }) {
  const location = useLocation();

  const [buttonText, setButtonText] = React.useState('');
  const [buttonClassName, setButtonClassName] = React.useState('');
  const [buttonVisibility, setButtonVisibility] = React.useState('movie-card__button_invisible');

  React.useEffect(() => {
    if (isSaved) {
      setButtonText('');
      setButtonClassName('movie-card__button-delete');
      setButtonVisibility('');
      if (location.pathname === '/saved-movies') {
        setButtonVisibility('movie-card__button_invisible');
      }
    } else {
      setButtonText('Сохранить');
      setButtonClassName('movie-card__button-save');
      setButtonVisibility('movie-card__button_invisible');
    }
  }, [isSaved]
  )

  function handleButtonChange(evt) {
    evt.preventDefault();
    if (isSaved) {
      onDeleteMovie(movie);
      setButtonClassName('movie-card__button-save');
      setButtonText('Сохранить');
    } else {
      onSaveMovie(movie);
      setButtonText('');
      setButtonClassName('movie-card__button-delete');
    }
  }

  function handleDelete(evt) {
    evt.preventDefault();
    onDeleteMovie(movie);
  }

  return (
    <div className='movie-card'>
      <a href={movie.trailerLink} className='movie-card__container' onMouseOver={handleMouseOver} onMouseLeave={handleMouseLeave} target="_blank" rel="noreferrer">
        <img src={ } className='movie-card__image' />
        {
          location.pathname === '/saved-movies' && (
            <button className={`movie-card__button movie-card__button-remove ${buttonVisibility}`} onClick={handleDelete}></button>
          )
        }
      </a>
      <div className='movie-card__description'>
        <p className='movie-card__name'>{movie.name}</p>
        <span className='movie-card__duration'>{`${hours} ${minutes}`}</span>
      </div>
    </div>
  )
}

我试着禁用缓存,在SavedMovies组件中添加了useEffect钩子,用于监视savedMovies状态的变化,但没有帮助。

t1rydlwq

t1rydlwq1#

试着像这样设置setSavedMovies

mainApi.deleteMovie(savedMovie._id)
  .then(() => {
    setSavedMovies(_savedMovies => _savedMovies.filter((m) => m._id !== movie._id));
  })
  .catch((err) => {
    console.log(err);
  })

如果这不起作用,在setSavedMovies之前添加一个console.log,确保它实际上正在执行。

相关问题