React 切换“显示全部”“显示获奖作品”功能异常问题求助
问题根因
- React状态更新为异步批量执行,
toggleWinner函数中调用filterWinner(!winner)后,当前作用域内的winner仍是更新前的旧值,后续判断逻辑基于旧状态执行,导致第一次点击过滤不生效,需点击两次才能触发过滤。 - 过滤获奖条目时直接覆盖了
movies状态存储的全量数据,第一次过滤完成后原始全量数据丢失,无法切回显示全部条目的状态。
修复方案
建议不要直接修改原始电影列表状态,改为在渲染阶段根据winner状态动态过滤数据,既不会丢失源数据,也能规避异步状态更新带来的逻辑不同步问题,修改后代码如下:
const MovieList = () => { // 存储全量电影数据,不再修改 const [movies, setMovies] = useState([]) const [showWinner, setShowWinner] = useState(false) // 重命名状态,语义更清晰 const fetchMovies = async () => { const res = await fetch('http://localhost:5000/data') const data = await res.json() return data } useEffect(() => { const getMovies = async () => { const moviesFromServer = await fetchMovies() setMovies(moviesFromServer) } getMovies() }, []) // 切换逻辑仅修改展示状态,使用函数式更新避免闭包问题 const toggleWinner = () => { setShowWinner(prev => !prev) } // 渲染前动态过滤要展示的列表 const displayMovies = showWinner ? movies.filter(movie => movie.winner === 'True') : movies return ( <div className="container"> <h1>Movies</h1> <hr /> <div> <Button onClick={toggleWinner} color="info"> {showWinner ? "显示全部" : "仅显示获奖条目"} </Button> </div> <div> <table className="table table-bordered table-striped"> <thead className="thead-dark"> <tr> <th>年份</th> <th>电影名称</th> <th>是否奥斯卡获奖</th> <th>国家</th> </tr> </thead> <tbody> {displayMovies.map(movie => ( <tr key={movie.id}> <td>{movie.year}</td> <td>{movie.filmName}</td> <td>{movie.winner}</td> <td>{movie.country}</td> </tr> ))} </tbody> </table> </div> </div> ) } export default MovieList;
内容的提问来源于stack exchange,提问作者Simon S.
相关产品推荐
相关产品推荐

