Реагируйте useState, не вызывая повторную визуализацию дочернего компонента - PullRequest
0 голосов
/ 18 февраля 2020

Кажется, я не могу понять, почему мой компонент MovieDetailCard не выполняет повторную визуализацию при изменении состояния mov ie. Я передаю объект mov ie. Когда я обновляю состояние, журнал выводит корректно в useEffect, но MovieDetailsCard никогда не получает обновленный объект.

    const MovieDetails = () => {
    const [movie, setMovie] = useState({});
    const { id } = useParams();
    const { poster } = useParams();

  useEffect(() => {
    const fetchMovie = async () => {
      const response = await fetch(
        `http://www.randyconnolly.com/funwebdev/3rd/api/movie/movies.php?id=${id}`
      );

      const data = await response.json();

      setMovie({ ...data });
    };

    fetchMovie();
  }, []);

  useEffect(() => {
    console.log(movie); // this successfully outputs when movie updates
  }, [movie]);

  return (
    <div className="row">
      <div className="col s12 m6">
        <MovieDetailsCard poster={poster} movie={movie} /> // this does not update
      </div>
      <div className="col s12 m6">
        <CastCrewCard />
      </div>
    </div>
  );
};

Ниже приведена MovieDeatailsCard. В useEffect console.log (mov ie) всегда возвращает ноль.

const MovieDetailsCard = ({ poster, movie }) => {
  useEffect(() => {
    console.log("in details");

    console.log(movie);
  }, []);
  return (
    <div className="card">
      <div className="card-content">
        <div className="row">
          <div className="col s6">
            <span className="card-title">Movie Title</span>
          </div>
          <div className="col s6 favouriteButton">
            <FavouriteButton className="waves-effect waves-light btn">
              <i className="material-icons">favorite</i>
            </FavouriteButton>
          </div>
        </div>

        <div className="row">
          <div className="col s12 m6">
            <img src={`https://image.tmdb.org/t/p/w342/${poster}.jpg`} alt="" />
          </div>
          <div className="col s12 m6">
            <p>{movie.title}</p>
          </div>
        </div>
      </div>
    </div>
  );
};

export default MovieDetailsCard;

Ответы [ 3 ]

0 голосов
/ 19 февраля 2020

Вы уверены, что собираетесь получать данные из API? Сайт не появляется. Попробуйте это для проверки API

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => console.log(json)

В объявлении состояния (useState) лучше объявить все ключи, которые вы собираетесь получить, от API

0 голосов
/ 19 февраля 2020

Спасибо, ребята за вклад. Это, кажется, решено сейчас. раньше я устанавливал данные с помощью setData (data), но когда я переключился на setData ({... data}), это работало!

0 голосов
/ 18 февраля 2020

По умолчанию эффекты запускаются после каждого завершенного рендера, но вы можете запускать их только при изменении определенных значений.

см .: https://reactjs.org/docs/hooks-reference.html#conditionally -firing-an-effect

Если вы хотите запустить эффект и очистить его только один раз (при монтировании и размонтировании), вы можете передать пустой массив ([]) в качестве второго аргумента. Это говорит React, что ваш эффект не зависит от каких-либо значений из реквизита или состояния, поэтому его не нужно повторно запускать. Это не обрабатывается как особый случай - это следует непосредственно из того, как всегда работает массив зависимостей.

попробуйте обновить зависимость useEffect, включив в нее [id] :

 useEffect(() => {
    const fetchMovie = async () => {
      const response = await fetch(
        `http://www.randyconnolly.com/funwebdev/3rd/api/movie/movies.php?id=${id}`
      );

      const data = await response.json();

      setMovie({ ...data });
    };

    fetchMovie();
  }, [id]);


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...