gpt4 book ai didi

javascript - 尽管有条件语句,组件仍以某种方式呈现

转载 作者:行者123 更新时间:2023-11-30 14:08:05 24 4
gpt4 key购买 nike

在我的 Home 组件上,在初始加载时,我循环遍历一个 URL 对象,并使用 Promise.all 确保它们同时解析。我构建了一个对象,并将其插入状态。开始时我有 loading: true,然后在将该对象插入状态后设置为 false:

主页组件:

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>
);
}
}

然后我让 body 像这样进行条件渲染,这样如果加载完成 (loading: false),那么我的 MovieDisplay 组件应该渲染,否则它仍在加载,所以显示 Loader 组件。

我确认这部分工作正常(如果我在 React Devtools 中搜索 Loaderloading: false存在,但是MovieDisplay 确实存在。

我通过 Home > MovieDisplay > MovieRow 中的 props 传递一个数据对象,然后遍历数组以显示更多成分。

但是,在初始加载时,似乎 MovieRow(最后一个嵌套子组件)以某种方式被快速安装了一秒钟,因为在控制台中它正在记录 4 undefined 在用适当的数据解析之前简要陈述。

主要问题:如果 Parent Component 没有渲染到 DOM,那么 Parent 里面的子组件也不应该被渲染,对吧?

第二个问题:尽管在 render() 函数中有条件,但我的应用程序中的所有组件是否有可能在初始加载时短暂呈现一秒钟?这是我唯一能想到的原因。

示例:如果 MovieDisplay 未呈现,则其中的所有内容(如 MovieRow)也不应呈现,对吗?

希望这不会太困惑...如果我需要编辑我的问题或详细说明,请告诉我。

最佳答案

.then 不解决 promise 。它让你在 promise 解决后获得值(value)

这是因为 JS 的异步特性。最初,当调用 componentDidMount 时,您设置 loading = true。

在 promise 完成之前(loading = true)react 渲染了 HOME 组件,这就是它调用 MovieDisplay 组件的原因。

尝试在调用 MovieDisplay 的地方添加一个额外的条件

 {this.state.loading && "check your data is filled in movies object" ? <Loader /> : <MovieDisplay movies={movies} />}

关于javascript - 尽管有条件语句,组件仍以某种方式呈现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54996398/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com