[英]Component render triggered, but DOM not updated
我的第一個React應用程序遇到了問題。 實際上,我有一個組件層次結構(我正在創建一個多媒體電影畫廊),單擊選項卡(由Movie組件表示)時,這些組件必須顯示單個電影的特定描述(SingleMovieDetails)。 問題在於,僅在第一次單擊時更新DOM,然后即使SingleMovieDetails道具發生更改,DOM仍會鎖定在第一個渲染的電影上。
這是我到目前為止編寫的代碼...
//Movie component
import React from "react";
import styles from "./Movie.module.scss";
import PropTypes from "prop-types";
class Movie extends React.Component{
constructor(props){
super(props);
this.imgUrl = `http://image.tmdb.org/t/p/w342/${this.props.movie.poster_path}`;
}
render(){
if(!this.props.size)
return <div onClick={this.props.callbackClick(this.props.movie.id)}
name={this.props.movie.id}
className={styles.movieDiv}
style={{backgroundImage: `url(${this.imgUrl})`}}></div>;
return <div onClick={() => this.props.callbackClick(this.props.movie.id)}
name={this.props.movie.id}
className={styles.movieDivBig}
style={{backgroundImage: `url(${this.imgUrl})`}}></div>;
}
}
Movie.propTypes = {
movie: PropTypes.any,
callbackClick: PropTypes.any
};
export default Movie;
SingleMovieDetails.js
import React from "react";
import styles from "./SingleMovieDetails.module.scss";
import Movie from "../Movie";
import SingleMovieDescription from "../SingleMovieDescription";
import MovieCast from "../MovieCast";
import SingleMovieRatings from "../SingleMovieRatings";
class SingleMovieDetails extends React.Component{
constructor(props){
super(props);
console.log(props);
this.state = props;
console.log('constructor', this.state.movie)
}
render(){
console.log('SMD', this.state.movie)
return (
<>
<div className={styles.container}>
<div className={styles.flayer}>
<Movie size={'big'} movie={this.state.movie}/>
</div>
<div className={styles.description}>
<SingleMovieDescription movie={this.state.movie}/>
<MovieCast></MovieCast>
</div>
<div className={styles.ratings}>
<SingleMovieRatings />
</div>
</div>
</>
);
}
}
export default SingleMovieDetails;
MovieCarousel.js
import React from "react";
import PropTypes from "prop-types";
import Movie from "../Movie";
import styles from "./MovieCarousel.module.scss";
import SingleMovieDetails from "../SingleMovieDetails";
class MovieCarousel extends React.Component {
constructor(props) {
super(props);
this.state = [];
this.callbackClickMovie = this.callbackClickMovie.bind(this);
}
callbackClickMovie(id) {
const singleMovieApi = `https://api.themoviedb.org/3/movie/${id}?api_key=b6f2e7712e00a84c50b1172d26c72fe9`;
fetch(singleMovieApi)
.then(function(response) {
return response.json();
})
.then(data => {
this.setState({ selected: data });
});
}
render() {
let details = null;
if (this.state.selected) {
details = <SingleMovieDetails movie={this.state.selected} />;
}
let counter = 6;
let movies = this.props.movies.map(el => {
let element = (
<Movie movie={el} callbackClick={this.callbackClickMovie} />
);
counter--;
if (counter >= 0) return element;
return;
});
let content = (
<>
<h2 className={styles.carouselTitle}>{this.props.title}</h2>
{movies}
{details}
</>
);
return content;
}
}
MovieCarousel.propTypes = {
children: PropTypes.any
};
export default MovieCarousel;
如果有人可以幫助我,我將不勝感激。 我已經待了兩天了,但我實在無法應付
您的問題僅與一個文件有關:SingleMovieDetails.js
在構造函數中,您正在設置組件狀態以使用props進行初始化(首次發送到組件)
但是在您的render()方法內部,您再次引用了該狀態 :
<Movie size={'big'} movie={this.state.movie}/>
總而言之,這並不是完全錯誤,但是您需要執行以下兩項操作之一:
添加一個使用nextPropsReceived更新組件狀態的方法(稱為生命周期方法:將接收道具,如果使用的是最新版本,則應使用:getDerivedStateFromProps)
首選選項 :影片組件不需要狀態,因此之后只需在render函數(this.props.movie)中使用props,就可以刪除構造函數,因為里面沒有特殊的東西。 :)
編輯:所以,這里要澄清一下:由於只設置了一次狀態(並非在每次生命周期更新中都調用構造函數),所以始終只保存第一個值。 從外部更改道具只會觸發render(),但不會再次啟動構造函數; D
這是因為在SingleMovieDetails
組件中,您是在狀態中存儲道具值,而不是在道具更改時更新狀態。 constructor
不會再次被調用,因此state始終具有初始值。
您有兩種選擇來解決此問題:
直接使用props值,而不是以狀態(首選方式)存儲數據。 像這樣:
class SingleMovieDetails extends React.Component { constructor(props) { super(props); } render() { return ( <> <div className={styles.container}> <div className={styles.flayer}> <Movie size={'big'} movie={this.props.movie}/> </div> <div className={styles.description}> <SingleMovieDescription movie={this.props.movie}/> <MovieCast></MovieCast> </div> <div className={styles.ratings}> <SingleMovieRatings /> </div> </div> </> ); } }
使用getDerivedStateFromProps ,並在更改道具時更新狀態值。
Movie
組件也存在相同的問題,請將此行放入render方法中,否則它將始終顯示相同的圖像:
const imgUrl = `http://image.tmdb.org/t/p/w342/${this.props.movie.poster_path}`
並使用此imgUrl變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.