React方法映射优化咨询:代码简化与状态传参优雅实现
React产品列表组件优化方案
你的原始代码:
import React, { useEffect, useState } from "react"; import axios from "axios"; import "./style.scss"; function Product() { function dataget() { axios.get(`http://localhost:9999/users/`).then((res) => { setProducts(res.data); }); } const deleteclick = (_id) => { axios.delete(`http://localhost:9999/users/${_id}`).then(() => { dataget(); }); }; const [products, setProducts] = useState([]); const [search, setSearch] = useState(""); useEffect(() => { dataget(); }, []); function handleclickplus() { setProducts([ ...products.sort((a, b) => a.title > b.title ? 1 : b.title > a.title ? -1 : 0 ), ]); } function handleclickminus() { setProducts([ ...products.sort((a, b) => b.title > a.title ? 1 : a.title > b.title ? -1 : 0 ), ]); } return ( <div> <button onClick={() => { handleclickminus(); }}>Çoxdan aza</button> <button onClick={() => { handleclickplus(); }}>Coxdan aza</button> <input type="text" placeholder="search" onChange={(e) => { setSearch(e.target.value); }} /> {products .filter((products) => products.title.toLowerCase().includes(search.toLowerCase())) .map((element) => { return ( <> <img src={element.imageUrl} alt="" /> <h1>{element.description}</h1> <h1>{element.title}</h1> <h1>${element.price}</h1> <button onClick={() => { deleteclick(element._id); }}> delete</button> </> ); })} </div> ); } export default Product;
一、代码简化优化
1. 合并排序逻辑,减少重复代码
用单个状态控制排序方向,替代两个独立的排序函数,避免代码冗余:
const [sortOrder, setSortOrder] = useState("asc"); // asc:升序,desc:降序 const handleSort = (order) => { setSortOrder(order); // 先复制数组再排序,避免修改原状态 const sorted = [...products].sort((a, b) => { return order === "asc" ? a.title.localeCompare(b.title) : b.title.localeCompare(a.title); }); setProducts(sorted); };
调用时直接传入排序方向:
<button onClick={() => handleSort("desc")}>从多到少</button> <button onClick={() => handleSort("asc")}>从少到多</button>
2. 简化函数与事件绑定
- 用
async/await重构数据请求,添加错误处理,提升可读性:
const fetchProducts = async () => { try { const res = await axios.get("http://localhost:9999/users/"); setProducts(res.data); } catch (err) { console.error("获取产品数据失败:", err); } }; const handleDelete = async (_id) => { try { await axios.delete(`http://localhost:9999/users/${_id}`); fetchProducts(); } catch (err) { console.error("删除产品失败:", err); } };
- 去掉事件绑定中的冗余括号,简化写法:
<input type="text" placeholder="搜索产品" onChange={(e) => setSearch(e.target.value)} /> <button onClick={() => handleDelete(element._id)}>删除</button>
3. 修复列表与命名问题
- 给列表元素添加唯一
key(React强制要求,避免渲染警告),同时优化语义化标签:
.map((element) => ( <div key={element._id} className="product-item"> <img src={element.imageUrl} alt={element.title} /> {/* 补充有意义的alt文本 */} <h3>{element.title}</h3> <p>{element.description}</p> <p className="price">${element.price}</p> <button onClick={() => handleDelete(element._id)}>删除</button> </div> ))
- 过滤函数参数避免与外层状态重名,提升可读性:
.filter((product) => product.title.toLowerCase().includes(search.toLowerCase()) )
优化后的完整代码:
import React, { useEffect, useState } from "react"; import axios from "axios"; import "./style.scss"; function Product() { const [products, setProducts] = useState([]); const [search, setSearch] = useState(""); const [sortOrder, setSortOrder] = useState("asc"); // 获取产品数据 const fetchProducts = async () => { try { const res = await axios.get("http://localhost:9999/users/"); setProducts(res.data); } catch (err) { console.error("获取产品数据失败:", err); } }; // 删除产品 const handleDelete = async (_id) => { try { await axios.delete(`http://localhost:9999/users/${_id}`); fetchProducts(); } catch (err) { console.error("删除产品失败:", err); } }; // 排序处理 const handleSort = (order) => { setSortOrder(order); const sortedProducts = [...products].sort((a, b) => { return order === "asc" ? a.title.localeCompare(b.title) : b.title.localeCompare(a.title); }); setProducts(sortedProducts); }; // 初始化加载数据 useEffect(() => { fetchProducts(); }, []); // 过滤后的产品列表 const filteredProducts = products.filter((product) => product.title.toLowerCase().includes(search.toLowerCase()) ); return ( <div className="product-container"> <div className="product-controls"> <button onClick={() => handleSort("desc")}>从多到少</button> <button onClick={() => handleSort("asc")}>从少到多</button> <input type="text" placeholder="搜索产品" value={search} onChange={(e) => setSearch(e.target.value)} /> </div> <div className="product-list"> {filteredProducts.map((element) => ( <div key={element._id} className="product-item"> <img src={element.imageUrl} alt={element.title} /> <h3>{element.title}</h3> <p>{element.description}</p> <p className="product-price">${element.price}</p> <button onClick={() => handleDelete(element._id)}>删除</button> </div> ))} </div> </div> ); } export default Product;
二、状态传递的优雅方案
如果需要跨组件传递状态或更新方法,可采用以下更简洁的方案:
- Context API:适合中等复杂度的状态共享,无需逐层传递props。创建Context后,在顶层组件提供状态和更新方法,子组件通过
useContext直接获取。 - 轻量状态管理库:比如Zustand、Jotai,无需繁琐配置,直接创建全局状态,任何组件都可读写,比Redux更轻量化。
- useReducer + Context:当状态更新逻辑复杂时,用
useReducer统一管理状态变更,结合Context传递dispatch和状态,替代多个useState与props传递。
内容的提问来源于stack exchange,提问作者Tore77o
相关产品推荐
相关产品推荐

