React Hooks点击切换按钮状态及按观影状态筛选列表问题求解
你的代码存在两处语法错误,修正后即可实现需求:
错误1:handleWatchedBtn 状态更新逻辑错误
你在修改对应id的电影对象时,没有展开原有属性,导致新生成的对象多了一层movie嵌套,watched字段没有直接挂载到电影对象上,状态切换无法生效。同时setMovie回调没有接收最新状态参数,异步场景下可能读取旧值。
修正后的代码:
function handleWatchedBtn(id) { setMovie(prevMovies => prevMovies.map((movie) => { if (movie.id === id) { // 展开原有对象,仅覆盖watched字段 return { ...movie, watched: !movie.watched }; } return movie; }) ); }
错误2:handleWatchedChange 筛选状态赋值错误
filterByWatch状态设计为存储字符串类型的筛选标记,你错误传入了对象结构,导致后续筛选逻辑判断失效。
修正后的代码:
function handleWatchedChange(filter) { // 直接传入筛选标记字符串即可 setfilterByWatch(filter); }
完整修正代码
import React, { useEffect, useState } from "react"; const App = () => { const [Movies, setMovie] = useState([]); const [Loading, setLoading] = useState(true); const [Keyword, setKeyword] = useState(""); const [OverSeven, setOverSeven] = useState(false); const [filterByWatch, setfilterByWatch] = useState("ALL"); useEffect(() => { fetch("http://my-json-server.typicode.com/bemaxima/fake-api/movies") .then((response) => response.json()) .then((response) => { setMovie( response.map((item) => ({ id: item.id, name: item.name, rate: item.rate, watched: false, })) ); setLoading(false); }); }, []); function handleWatchedBtn(id) { setMovie(prevMovies => prevMovies.map((movie) => { if (movie.id === id) { return { ...movie, watched: !movie.watched }; } return movie; }) ); } function handleWatchedChange(filter) { setfilterByWatch(filter); } function handleKeywordChange(e) { setKeyword(e.target.value); } function handleOverSevenChange(e) { setOverSeven(e.target.checked); } function filterItems() { return Movies.filter((item) => item.name.toLowerCase().includes(Keyword.toLowerCase()) ) .filter((item) => (OverSeven ? item.rate > 7 : true)) .filter((item) => filterByWatch === "ALL" ? true : item.watched === (filterByWatch === "WATCHED") ); } if (Loading) { return "Please wait..."; } return ( <div> <div> <div> Keyword <input type="text" value={Keyword} onChange={handleKeywordChange} /> </div> <div> <button onClick={() => handleWatchedChange("ALL")}>all</button> <button onClick={() => handleWatchedChange("WATCHED")}>watch</button> <button onClick={() => handleWatchedChange("NOT_WATCHED")}> not watch </button> </div> <div> Only over 7.0 <input type="checkbox" checked={OverSeven} onChange={handleOverSevenChange} /> </div> <div> <ul> {filterItems().map((movie) => ( <li data-id={movie.id} key={movie.id}> {`${movie.name} ${movie.rate}`}{" "} <button onClick={() => handleWatchedBtn(movie.id)}> {movie.watched ? "Watched" : " Not watched"} </button> </li> ))} </ul> </div> </div> </div> ); }; export default App;
内容的提问来源于stack exchange,提问作者Negin
相关产品推荐
相关产品推荐

