首页 > 解决方案 > 如何将每个列表项的观看按钮切换为观看,反之亦然

问题描述

我为 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;

标签: javascripthtmlreactjs

解决方案


是的。你说的对。您已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>

推荐阅读