React按产品value值排序后页面不刷新该如何解决?
问题原因
你遇到的问题核心是两个错误导致的:
- 直接原地修改State且引用未变化
你编写的let actual_show = products只是将State中数组的引用赋值给了新变量,并没有创建新的数组。而JavaScript的Array.sort()是原地排序方法,会直接修改原数组本身,不会生成新数组。当你调用setProducts(actual_show)时,传入的还是原数组的引用,React做State更新的浅比较时会判定State没有发生变化,因此不会触发组件的重渲染。 - 语法逻辑错误
你的else if (newOrder === "Low price")分支缺少闭合的大括号,导致后续的console.log和setProducts逻辑只有在选择「Low price」选项时才会执行,选择「High price」时根本不会触发State更新操作。
修复方案
- 排序前先对原
products数组做浅拷贝,生成新数组后再执行排序操作,保证传给setProducts的是全新的数组引用,触发React重渲染 - 补全
else if分支的闭合大括号,保证逻辑在两种排序选项下都能正常执行
修正后的代码
function ProductsPage() { const [products, setProducts] = useState([]) useEffect(() => { /* 这里是你从后端获取数据后setProducts的逻辑 */ }, []) const orderShowing = (e) => { // 先浅拷贝原数组,生成新数组 let actual_show = [...products] let newOrder = e.target.value; if (newOrder === "High price") { actual_show.sort((a, b) => b.value - a.value) } else if (newOrder === "Low price") { actual_show.sort((a, b) => a.value - b.value) } // 补全闭合大括号 console.log(actual_show) setProducts(actual_show) } return ( <div> <select id="productsOrder" onChange={orderShowing}> <option>High price</option> <option>Low price</option> </select> <h2>Products</h2> {/* 注意map渲染列表要加唯一key属性,避免React报错 */} {products.map((p) => { return <p key={p.name}>{p.name}</p>})} </div> ) }
额外优化提示:数字类型的排序直接用
a.value - b.value的写法即可,不需要写多分支的三元判断,逻辑更简洁。另外列表渲染时建议给每一项加唯一的key属性,避免React抛出警告。
内容的提问来源于stack exchange,提问作者Víctor Donat
相关产品推荐
相关产品推荐

