React分页功能中移除首个子元素并替换为新子元素的实现问题
你完全不需要手动移除DOM子元素,React是数据驱动渲染的,只要保证recipes状态每次只存储当前页的食谱数据,页面就会自动只展示当前分页内容,你现在的问题是代码存在bug导致接口请求参数异常,才会出现结果未替换的问题。
需修改的问题点
- 请求URL的
from参数后缺少等于号,导致分页参数无法被接口正确识别,返回的结果超出了当前页的范围 - 分页结束值
to用了未更新的pagination变量计算,新搜索重置页码时会出现参数不匹配的问题 - 冗余代码:
recipes !== []的判断完全无效(数组为引用类型,该判断永远返回true),存储上一次搜索词的useEffect缺少依赖数组,会触发不必要的重复执行
修正后完整代码
import './App.css'; import React, {useState, useEffect, useRef} from "react"; import Recipe from './components/recipes/Recipe.jsx'; import { Row, Col } from 'react-bootstrap'; function App() { const [recipes, setRecipes] = useState([]); const [search, setSearch]= useState(''); const [query, setQuery] = useState(''); const [pagination, setPagination] = useState(0); const prevSearchIdRef = useRef(); // 补充依赖数组,只在query变化时更新 useEffect(()=>{ prevSearchIdRef.current = query; }, [query]); const prevSearch = prevSearchIdRef.current const fetchRecipes = async () => { let currentPagination = pagination; if(prevSearch !== query){ currentPagination = 0; setPagination(0); } // 修正from参数的等于号,to用currentPagination计算 const response = await fetch(`https://api.edamam.com/search?q=${query}&app_id=8f7859bc&app_key=f7c43e28aea5bc242e86fe0f089dda3c&from=${currentPagination}&to=${currentPagination + 5}`) const data = await response.json(); // 这里直接替换state为当前页的结果,本身就不会追加 setRecipes(data.hits); } const updateSearch = e => { setSearch(e.target.value); }; const getSearch = e => { e.preventDefault(); setQuery(search); setSearch(''); } const prevClick = () => { if(pagination === 0){ return; } setPagination(pagination-5); } const nextClick = () => { setPagination(pagination+5); } useEffect(() => { fetchRecipes(); }, [query, pagination]) return ( <div className="App"> <div className="Nav">NAV BAR COMPONENT HERE</div> <div className="search-container"> <form onSubmit={getSearch} className="search-form"> <input className="search-bar" type="text" placeholder="Search recipes" value={search} onChange={updateSearch} /> <button className="search-button" type="submit">Search</button> </form> </div> <br/> <h2>Your search results for "{query}"</h2> <div className="recipeList"> {recipes?.length ? ( <Row> {/* 删掉无用的recipes !== []判断 */} {recipes.map((recipe, index) => <Col><Recipe recipe={recipe.recipe} key={index} /></Col>)} </Row> ):( <div>No recipes found. Please try another search.</div> ) } </div> <div> <button onClick={prevClick}>Prev</button> <button onClick={nextClick}>Next</button> </div> </div> ); } export default App;
内容的提问来源于stack exchange,提问作者jimmyh920
相关产品推荐
相关产品推荐

