javascript - 如何将每个列表项的观看按钮切换为观看,反之亦然
问题描述
我为 isWatched 创建了一个状态,如果 isWatched === true,那么我希望按钮显示“Watched”,如果它为 false,则按钮显示“Watch”我希望能够在每个按钮上切换并有条件地呈现单击时按钮的名称。然而,虽然状态在点击时发生了变化,但按钮的名称并没有改变。我相信这是因为需要在 return 语句中定义按钮才能更新,但我在 handleSearch 方法中的 setState 条件下定义了所有逻辑,所以我不确定如何在不必重构所有内容的情况下解决这个问题。我还有一个问题,我需要隔离每个按钮,因为如果我改变状态,所有按钮都会改变。
import React from 'react';
import movies from './movieData';
const movieTitles = movies.map(movie => movie.title);
class SearchBar extends React.Component {
constructor(props) {
super(props);
this.state = {
searchQuery: '',
searchedMovies: [],
isMovieFound: null,
isWatched: false
}
}
handleQuery = e => {
this.setState({
searchQuery: e.target.value
});
}
handleWatched = () => {
this.setState(prevState => ({
isWatched: !prevState.isWatched
}));
}
handleSearch = () => {
if (movieTitles.filter(movie => movie.toLowerCase()
.includes(this.state.searchQuery.toLowerCase())).length === 0) {
this.setState({ isMovieFound: false, searchedMovies: [], searchQuery: '' });
} else {
this.setState({
searchedMovies: movieTitles.filter(movie =>
movie.toLowerCase().includes(this.state.searchQuery.toLowerCase()))
.map(movie => <li key={movie}>{movie}<button className="watchBtn" onClick={this.handleWatched}>{this.state.isWatched ? 'Watched' : 'Watch'}</button></li>),
isMovieFound: true,
searchQuery: ''
});
}
}
render() {
return (
<div>
<input
type="text"
placeholder="Search for a movie.."
name="searchQuery"
value={this.state.searchQuery}
onChange={this.handleQuery}
/>
<button
onClick={this.handleSearch}
>
Search
</button>
<br />
<ul>
{this.state.searchedMovies}
</ul>
{this.state.isMovieFound === false && <span>No Movie Found</span>}
</div>
);
}
}
export default SearchBar;
解决方案
是的。你说的对。您已searchedMovies
在单击“搜索”按钮时呈现。我不明白为什么要在状态中存储 UI 元素。这是一个不好的做法。尝试将过滤后的电影存储在您的商店中,并在渲染方法本身中编写渲染逻辑,如下所示:
handleSearch = () => {
if (movieTitles.filter(movie => movie.toLowerCase()
.includes(this.state.searchQuery.toLowerCase())).length === 0) {
this.setState({ isMovieFound: false, searchedMovies: [], searchQuery: '' });
} else {
this.setState({
searchedMovies: movieTitles.filter(movie => movie.toLowerCase().includes(this.state.searchQuery.toLowerCase())),
isMovieFound: true,
searchQuery: ''
});
}
并在渲染函数中添加以下代码
<ul>
{this.state.searchedMovies.map(movie => <li key={movie}>{movie}<button className="watchBtn" onClick={this.handleWatched}>{this.state.isWatched ? 'Watched' : 'Watch'}</button></li>)}
</ul>
推荐阅读
- python - 使用其他中间模块导入不起作用
- authentication - 仅针对管理员前缀 CakePHP 4 的身份验证
- api - 这是 Bitstamp api 中的时间戳错误吗?
- kubernetes - 如何从 kubernetes 集群的 ansible(注册标准输出)初始化中获取最后两行
- android - Android HTML 类支持哪些 HTML 标签以及如何使用 HtmlCompat?
- javascript - 解析来自同一来源的不同 javascript
- angular - 尝试从 Google OAuth2 撤消端点撤消访问令牌时出现 404
- c# - 了解 C# 事件处理程序:为什么没有事件?
- android - Play商店显示在模拟器上找不到的项目
- android - TDD 和 BDD with mockk for Android