React预填充API数据的滑块拖动后跳回默认值,如何让用户输入优先
问题根源
你目前的bug主要来自三个逻辑错误:
- useEffect依赖项包含了
MovieResults,每次setMovieResults触发状态更新后,都会重新执行整个useEffect逻辑,导致反复重置滑块值 - fetch的异步回调逻辑写法错误:
setMovieResults是异步更新,你紧接着遍历的MovieResults还是更新前的旧值,根本拿不到刚拉取的接口数据 - 没有标记用户是否已经手动修改过滑块值,所以即使用户调整了评分,后续useEffect触发时还是会被接口返回的历史评分覆盖
修改方案
- 新增一个状态标记用户是否已经手动修改过评分,仅在用户未修改的情况下才用接口返回值预填充
- 把
MovieResults从useEffect依赖项中移除,拿到接口返回数据后直接遍历新拿到的结果,不要依赖状态中的旧值 - 用户拖动滑块时同步修改「已手动修改」的标记,后续不再自动覆盖用户设置的值
修改后完整代码
const [ user ] = useContext(Context); const location = useLocation(); const { pathname } = location; const splitLocation = pathname.split("/"); const movieId = splitLocation[2]; const [ MovieResults, setMovieResults ] = useState([]); const [ value, setValue ] = useState(5); // 新增标记:用户是否已经手动修改过评分 const [isUserModified, setIsUserModified] = useState(false); useEffect(() => { let isMounted = true; fetch(`${API_URL}account/xxxxxxxx/rated/movies?api_key=${API_KEY}&session_id=${user.sessionId}&sort_by=created_at.desc`) .then(res => res.json()) .then(data => { if (!isMounted) return setMovieResults(data.results) // 直接遍历刚拿到的接口数据,不要用状态里的MovieResults const targetMovie = data.results.find(item => item.id.toString() === movieId.toString()) // 仅在用户未手动修改过的情况下才预填充值 if (targetMovie && !isUserModified) { setValue(targetMovie.rating) } }) return () => { isMounted = false }; // 移除MovieResults依赖,避免循环触发 },[user.sessionId, movieId, isUserModified]); const changeSlider = (e) => { setValue(e.currentTarget.value); // 用户手动修改后标记为true,后续不再自动覆盖 setIsUserModified(true) }; return ( <div> <input type="range" min="1" max="10" className="rate-slider" value={value} onChange={e => changeSlider(e)} /> {value} <p> <button className="rate-button" onClick={() => callback(value)}>提交评分</button> </p> </div> )
内容的提问来源于stack exchange,提问作者user6221709
相关产品推荐
相关产品推荐

