[英]Component is somehow rendering despite conditional statement
在Home
组件上,在初始加载时,我遍历URL对象,并使用Promise.all
来确保它们同时解析。 我构造一个对象,并将其推入状态。 首先,我loading: true
,然后在将对象推入状态时设置为false
:
Home Component
:
class Home extends Component {
state = {
searchTerm: null,
movies: {
trending: {},
topRated: {},
nowPlaying: {},
upcoming: {}
},
loading: false
};
componentDidMount() {
this.getInitalMovies();
}
getInitalMovies = () => {
const API_KEY = process.env.REACT_APP_API_KEY;
//set loading to true
this.setState({ loading: true });
//create an object with all movie URLs
const allMovieURLs = {
trending: `https://api.themoviedb.org/3/trending/movie/day?api_key=${API_KEY}`,
topRated: `https://api.themoviedb.org/3/movie/top_rated?api_key=${API_KEY}&language=en-US&page=1`,
nowPlaying: `https://api.themoviedb.org/3/movie/now_playing?api_key=${API_KEY}&language=en-US&page=1`,
upcoming: `https://api.themoviedb.org/3/movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`
};
//break down the movieURL object into entries, fetch the URL, and reassign entries with actual data
//encapsulate within a Promise.all to ensure they all resolve at the same time.
const moviePromises = Promise.all(
Object.entries(allMovieURLs).map(entry => {
const [key, url] = entry;
return fetch(url).then(res => res.json().then(data => [key, data]));
})
);
//with the returned promise from Promise.all, reconstruct the array of entries back into an object with relevant key pair values
const movies = moviePromises.then(movieArr => {
const dataObj = {};
for (const [movie, movieData] of movieArr) {
dataObj[movie] = movieData;
}
return dataObj;
});
//with the returned object, push it into current state, then turn off loading
movies.then(movieObj =>
this.setState({ movies: movieObj, loading: false })
);
};
render() {
const { movies } = this.state;
return (
<div className='App'>
<Header
submitHandler={this.submitHandler}
changeHandler={this.changeHandler}
/>
<HeroImage />
{this.state.loading ? <Loader /> : <MovieDisplay movies={movies} />}
</div>
);
}
MovieDisplay
组件:
export default class MovieDisplay extends Component {
render() {
const { movies } = this.props;
return (
<div>
<MovieRow movies={movies.trending.results} movieType='trending' />
<MovieRow movies={movies.topRated.results} movieType='top rated' />
<MovieRow movies={movies.nowPlaying.results} movieType='now playing' />
<MovieRow movies={movies.upcoming.results} movieType='upcoming' />
</div>
);
}
}
MovieRow
组件:
export default class MovieRow extends Component {
render() {
const { movieType, movies } = this.props;
return (
<div>
<div className='row-title'>{movieType}</div>
{console.log(movies)} //This part seems to somehow mount even when conditional rendering says it shouldn't!
<Slider {...settings} />
</div>
);
}
}
然后,我让主体像这样进行条件渲染,以便如果加载完成( loading: false
),则我的MovieDisplay
组件应该进行渲染,否则它仍在加载,因此请显示Loader
组件。
我确认这部分正在工作(如果我在Loader
时搜索React Devtools来查找Loader
loading: false
则不存在,但MovieDisplay
确实存在。
我通过Home
> MovieDisplay
> MovieRow
通过props传递数据对象,然后循环遍历数组以显示更多组件。
但是,在初始加载时, MovieRow
(最后一个嵌套的子组件)似乎以某种方式挂载了很MovieRow
,因为在控制台中,在解析适当的数据之前,它会简要记录4个undefined
语句。
主要问题:如果没有将父组件呈现给DOM,那么父内部的子组件也不应呈现,对吗?
次要问题:尽管render()
函数中有条件,但我的应用程序中的所有组件是否有可能在初始加载时短暂地进行了一秒钟的render()
? 这是我能想到的唯一原因。
示例:如果未渲染MovieDisplay
,则其中的所有内容(如MovieRow
也不应渲染,对吗?
希望这不会太令人困惑...请让我知道我是否需要编辑问题或进行详细说明。
你可以尝试一下:
{this.state.loading && <Loader />}
{!this.state.loading && <MovieDisplay movies={movies} />}
.then
无法解决诺言。 它使您在兑现诺言后获得价值
这是由于JS的异步特性。 最初,在调用componentDidMount时,将loading设置为true。
在诺言完成之前(loading = true)react渲染HOME组件,这就是它调用MovieDisplay组件的原因。
尝试在调用MovieDisplay的地方添加其他条件
{this.state.loading && "check your data is filled in movies object" ? <Loader /> : <MovieDisplay movies={movies} />}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.